⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncbimtx.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    {    }    ~CPthreadCond(void)    {        if ( m_Initialized ) {            pthread_cond_destroy(&m_Handle);        }    }    operator pthread_cond_t*(void) { return &m_Handle; }    operator pthread_cond_t&(void) { return m_Handle; }protected:    pthread_cond_t  m_Handle;    bool            m_Initialized;};#endifclass CInternalRWLock{public:    CInternalRWLock(void);    // Platform-dependent RW-lock data#if defined(NCBI_WIN32_THREADS)    CWindowsSemaphore   m_Rsema;    CWindowsSemaphore   m_Wsema;    CFastMutex          m_Mutex;#elif defined(NCBI_POSIX_THREADS)    CPthreadCond        m_Rcond;    CPthreadCond        m_Wcond;    CFastMutex          m_Mutex;#endif};inlineCInternalRWLock::CInternalRWLock(void)#if defined(NCBI_WIN32_THREADS)    : m_Rsema(1, 1), m_Wsema(1, 1)#endif{}///////////////////////////////////////////////////////////////////////////////  CRWLock:://CRWLock::CRWLock(void)    : m_RW(new CInternalRWLock),      m_Count(0){#if defined(_DEBUG)    m_Readers.reserve(16);#endif}CRWLock::~CRWLock(void){}void CRWLock::ReadLock(void){#if defined(NCBI_NO_THREADS)    return;#else    // Lock mutex now, unlock before exit.    // (in fact, it will be unlocked by the waiting function for a while)    CFastMutexGuard guard(m_RW->m_Mutex);    CThreadSystemID self_id = CThreadSystemID::GetCurrent();    if ( m_Count < 0 ) {        if ( m_Owner.Is(self_id) ) {            // if W-locked by the same thread - update W-counter            m_Count--;        }        else {            // W-locked by another thread#if defined(NCBI_WIN32_THREADS)            HANDLE obj[2];            DWORD  wait_res;            obj[0] = m_RW->m_Mutex.GetHandle();            obj[1] = m_RW->m_Rsema;            xncbi_Validate(ReleaseMutex(m_RW->m_Mutex.GetHandle()),                           "CRWLock::ReadLock() - release mutex error");            wait_res = WaitForMultipleObjects(2, obj, TRUE, INFINITE);            xncbi_Validate(wait_res >= WAIT_OBJECT_0  &&                           wait_res < WAIT_OBJECT_0 + 2,                           "CRWLock::ReadLock() - R-lock waiting error");            // Success, check the semaphore            xncbi_Validate(m_RW->m_Rsema.Release() == 0,                           "CRWLock::ReadLock() - invalid R-semaphore state");            if (m_Count == 0) {                xncbi_Validate(WaitForSingleObject(m_RW->m_Wsema,                                                   0) == WAIT_OBJECT_0,                               "CRWLock::ReadLock() - "                               "failed to lock W-semaphore");            }#elif defined(NCBI_POSIX_THREADS)            while (m_Count < 0) {                xncbi_Validate(pthread_cond_wait(m_RW->m_Rcond,                                                 m_RW->m_Mutex.GetHandle())                               == 0,                               "CRWLock::ReadLock() - R-lock waiting error");            }#else            // Can not be already W-locked by another thread without MT            xncbi_Validate(0,                           "CRWLock::ReadLock() - "                           "weird R-lock error in non-MT mode");#endif            xncbi_Validate(m_Count >= 0,                           "CRWLock::ReadLock() - invalid readers counter");            m_Count++;        }    }    else {#if defined(NCBI_WIN32_THREADS)        if (m_Count == 0) {            // Unlocked            // Lock against writers            xncbi_Validate(WaitForSingleObject(m_RW->m_Wsema, 0)                           == WAIT_OBJECT_0,                           "CRWLock::ReadLock() - "                           "can not lock W-semaphore");        }#endif        m_Count++;    }#if defined(_DEBUG)    // Remember new reader    if (m_Count > 0) {        m_Readers.push_back(self_id);    }#endif#endif}bool CRWLock::TryReadLock(void){#if defined(NCBI_NO_THREADS)    return true;#else    CFastMutexGuard guard(m_RW->m_Mutex);    CThreadSystemID self_id = CThreadSystemID::GetCurrent();    if (m_Count < 0) {        if ( m_Owner.IsNot(self_id) ) {            // W-locked by another thread            return false;        }        else {            // W-locked, try to set R after W if in the same thread            m_Count--;            return true;        }    }    // Unlocked - do R-lock#if defined(NCBI_WIN32_THREADS)    if (m_Count == 0) {        // Lock W-semaphore in MSWIN        xncbi_Validate(WaitForSingleObject(m_RW->m_Wsema, 0)                       == WAIT_OBJECT_0,                       "CRWLock::TryReadLock() - "                       "can not lock W-semaphore");    }#endif    m_Count++;#if defined(_DEBUG)    m_Readers.push_back(self_id);#endif    return true;#endif}void CRWLock::WriteLock(void){#if defined(NCBI_NO_THREADS)    return;#else    CFastMutexGuard guard(m_RW->m_Mutex);    CThreadSystemID self_id = CThreadSystemID::GetCurrent();    if ( m_Count < 0 && m_Owner.Is(self_id) ) {        // W-locked by the same thread        m_Count--;    }    else {        // Unlocked or RW-locked by another thread        // Look in readers - must not be there        xncbi_Validate(find(m_Readers.begin(), m_Readers.end(), self_id)                       == m_Readers.end(),                       "CRWLock::WriteLock() - "                       "attempt to set W-after-R lock");#if defined(NCBI_WIN32_THREADS)        HANDLE obj[3];        obj[0] = m_RW->m_Rsema;        obj[1] = m_RW->m_Wsema;        obj[2] = m_RW->m_Mutex.GetHandle();        DWORD wait_res;        if (m_Count == 0) {            // Unlocked - lock both semaphores            wait_res = WaitForMultipleObjects(2, obj, TRUE, 0);            xncbi_Validate(wait_res >= WAIT_OBJECT_0  &&                           wait_res < WAIT_OBJECT_0+2,                           "CRWLock::WriteLock() - "                           "error locking R&W-semaphores");        }        else {            // Locked by another thread - wait for unlock            xncbi_Validate(ReleaseMutex(m_RW->m_Mutex.GetHandle()),                           "CRWLock::ReadLock() - release mutex error");            wait_res = WaitForMultipleObjects(3, obj, TRUE, INFINITE);            xncbi_Validate(wait_res >= WAIT_OBJECT_0  &&                           wait_res < WAIT_OBJECT_0+3,                           "CRWLock::WriteLock() - "                           "error locking R&W-semaphores");        }#elif defined(NCBI_POSIX_THREADS)        while (m_Count != 0) {            xncbi_Validate(pthread_cond_wait(m_RW->m_Wcond,                                             m_RW->m_Mutex.GetHandle()) == 0,                           "CRWLock::WriteLock() - "                           "error locking R&W-conditionals");        }#endif        xncbi_Validate(m_Count >= 0,                       "CRWLock::WriteLock() - invalid readers counter");        m_Count = -1;        m_Owner.Set(self_id);    }    // No readers allowed    _ASSERT(m_Readers.empty());#endif}bool CRWLock::TryWriteLock(void){#if defined(NCBI_NO_THREADS)    return true;#else    CFastMutexGuard guard(m_RW->m_Mutex);    CThreadSystemID self_id = CThreadSystemID::GetCurrent();    if ( m_Count < 0 ) {        // W-locked        if ( m_Owner.IsNot(self_id) ) {            // W-locked by another thread            return false;        }        // W-locked by same thread        m_Count--;    }    else if ( m_Count > 0 ) {        // R-locked        return false;    }    else {        // Unlocked - do W-lock#if defined(NCBI_WIN32_THREADS)        // In MSWIN lock semaphores        HANDLE obj[2];        obj[0] = m_RW->m_Rsema;        obj[1] = m_RW->m_Wsema;        DWORD wait_res;        wait_res = WaitForMultipleObjects(2, obj, TRUE, 0);        xncbi_Validate(wait_res >= WAIT_OBJECT_0  &&                       wait_res < WAIT_OBJECT_0 + 2,                       "CRWLock::TryWriteLock() - "                       "error locking R&W-semaphores");#endif        m_Count = -1;        m_Owner.Set(self_id);    }    // No readers allowed    _ASSERT(m_Readers.empty());    return true;#endif}void CRWLock::Unlock(void){#if defined(NCBI_NO_THREADS)    return;#else    CFastMutexGuard guard(m_RW->m_Mutex);    CThreadSystemID self_id = CThreadSystemID::GetCurrent();    if (m_Count < 0) {        // Check it is R-locked or W-locked by the same thread        xncbi_Validate(m_Owner.Is(self_id),                       "CRWLock::Unlock() - "                       "RWLock is locked by another thread");        if ( ++m_Count == 0 ) {            // Unlock the last W-lock#if defined(NCBI_WIN32_THREADS)            xncbi_Validate(m_RW->m_Rsema.Release() == 0,                           "CRWLock::Unlock() - invalid R-semaphore state");            xncbi_Validate(m_RW->m_Wsema.Release() == 0,                           "CRWLock::Unlock() - invalid R-semaphore state");#elif defined(NCBI_POSIX_THREADS)            xncbi_Validate(pthread_cond_broadcast(m_RW->m_Rcond) == 0,                           "CRWLock::Unlock() - error signalling unlock");            xncbi_Validate(pthread_cond_signal(m_RW->m_Wcond) == 0,                           "CRWLock::Unlock() - error signalling unlock");#endif        }#if defined(_DEBUG)        // Check if the unlocking thread is in the owners list        _ASSERT(find(m_Readers.begin(), m_Readers.end(), self_id)               == m_Readers.end());#endif    }    else {        xncbi_Validate(m_Count != 0,                       "CRWLock::Unlock() - RWLock is not locked");        if ( --m_Count == 0 ) {            // Unlock the last R-lock#if defined(NCBI_WIN32_THREADS)            xncbi_Validate(m_RW->m_Wsema.Release() == 0,                           "CRWLock::Unlock() - invalid W-semaphore state");#elif defined(NCBI_POSIX_THREADS)            xncbi_Validate(pthread_cond_signal(m_RW->m_Wcond) == 0,                           "CRWLock::Unlock() - error signaling unlock");#endif        }#if defined(_DEBUG)        // Check if the unlocking thread is in the owners list        vector<CThreadSystemID>::iterator found =            find(m_Readers.begin(), m_Readers.end(), self_id);        _ASSERT(found != m_Readers.end());        m_Readers.erase(found);        if ( m_Count == 0 ) {            _ASSERT(m_Readers.empty());        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -