📄 switrdmonitor.cpp
字号:
rc = ::unlockMutex(_globalLock);
if (rc != SUCCESS || _mutex == NULL)
{
return FAILURE;
}
if (!newMutex)
{
rc = ::lockMutex(_mutex->_handle);
}
}
else
{
rc = ::lockMutex(_mutex->_handle);
}
if (rc == SUCCESS)
{
_ownerThread = threadId;
_lockCount = 1;
}
return rc;
}
// unlock
// Refer to SWItrdMonitor.hpp for doc.
int SWItrdMonitor::unlock()
{
VXIthreadID threadId = VXItrdThreadGetID();
if (threadId != _ownerThread)
{
return NOT_OWNER;
}
int rc = SUCCESS;
if (_policy == POOLED)
{
::lockMutex(_globalLock);
if (--_lockCount == 0)
{
_ownerThread = (VXIthreadID) -1;
rc = ::unlockMutex(_mutex->_handle);
if (--_mutex->_count == 0)
{
_mutex->_next = _freeMutexList;
_freeMutexList = _mutex;
_mutex = NULL;
}
}
::unlockMutex(_globalLock);
}
else
{
if (--_lockCount == 0)
{
_ownerThread = (VXIthreadID) -1;
rc = ::unlockMutex(_mutex->_handle);
}
}
return rc;
}
// wait
// Refer to SWItrdMonitor.hpp for doc.
int SWItrdMonitor::wait()
{
return wait(INFINITE,NULL);
}
// wait
// Refer to SWItrdMonitor.hpp for doc.
int SWItrdMonitor::wait(unsigned long millisecs, bool *expiredF)
{
// body
VXIthreadID threadId = VXItrdThreadGetID();
if (threadId != _ownerThread)
{
return NOT_OWNER;
}
int count = _lockCount;
_ownerThread = (VXIthreadID) -1;
_lockCount = 0;
HandleListItem *listItem = getHandle();
int rc = waitForEvent(_mutex->_handle, listItem->_handle,
millisecs, expiredF);
resetHandle(listItem);
if (rc == SUCCESS)
{
_ownerThread = threadId;
_lockCount = count;
}
return rc;
}
// notify
// Refer to SWItrdMonitor.hpp for doc.
int SWItrdMonitor::notify()
{
// body
VXIthreadID threadId = VXItrdThreadGetID();
if (threadId != _ownerThread)
{
return NOT_OWNER;
}
int rc = SUCCESS;
::lockMutex(_globalLock);
if (_firstWaitingThread != NULL)
{
#ifdef _WIN32
rc = ::notifyEvent(_firstWaitingThread->_handle, false);
// Remove the handle from the waiting threads list.
HandleListItem *tmp = _firstWaitingThread;
_firstWaitingThread = _firstWaitingThread->_next;
tmp->_next = NULL;
if (_firstWaitingThread == NULL)
_lastWaitingThread = NULL;
else
_firstWaitingThread->_prev = NULL;
#else
rc = ::notifyEvent(_firstWaitingThread->_handle, false);
#endif
}
::unlockMutex(_globalLock);
return rc;
}
// notifyAll
// Refer to SWItrdMonitor.hpp for doc.
int SWItrdMonitor::notifyAll()
{
// body
VXIthreadID threadId = VXItrdThreadGetID();
if (threadId != _ownerThread)
{
return NOT_OWNER;
}
::lockMutex(_globalLock);
int rc = notifyAllHandles();
::unlockMutex(_globalLock);
return rc;
}
int SWItrdMonitor::notifyAllHandles()
{
int rc = SUCCESS;
#ifdef _WIN32
while (_firstWaitingThread != NULL)
{
HandleListItem *tmp = _firstWaitingThread;
_firstWaitingThread = _firstWaitingThread->_next;
tmp->_next = tmp->_prev = NULL;
if (notifyEvent(tmp->_handle, true) != SUCCESS)
rc = FAILURE;
}
_lastWaitingThread = NULL;
#else
if (_firstWaitingThread != NULL)
{
rc = notifyEvent(_firstWaitingThread->_handle, true);
}
#endif
return rc;
}
#ifdef _WIN32
SWItrdMonitor::HandleListItem *SWItrdMonitor::getHandle()
{
HandleListItem *handle = NULL;
::lockMutex(_globalLock);
if (_freeThreadList == NULL)
{
handle = new HandleListItem;
// No need to initialize _owner, _next and _prev at this point. They are
// initialized below.
HANDLE *k = new HANDLE;
*k = CreateEvent(NULL, FALSE, FALSE, NULL);
handle->_handle = k;
}
else
{
// Take the first NT event in the free list and make sure it is reset
// Altough it should be.
handle = _freeThreadList;
_freeThreadList = handle->_next;
ResetEvent(*(static_cast<HANDLE *>(handle->_handle)));
}
// Insert in list of pending notifications.
if (_lastWaitingThread == NULL)
{
// empty list.
_lastWaitingThread = _firstWaitingThread = handle;
handle->_prev = handle->_next = NULL;
}
else
{
// add to the end of the list
_lastWaitingThread->_next = handle;
handle->_prev = _lastWaitingThread;
handle->_next = NULL;
_lastWaitingThread = handle;
}
::unlockMutex(_globalLock);
return handle;
}
void SWItrdMonitor::resetHandle(HandleListItem *handle)
{
::lockMutex(_globalLock);
ResetEvent(*(static_cast<HANDLE *>(handle->_handle)));
// Remove from the pending list.
if (handle == _firstWaitingThread)
{
// The handle is the first one on the pending list.
_firstWaitingThread = handle->_next;
if (handle == _lastWaitingThread) _lastWaitingThread = NULL;
}
else if (handle == _lastWaitingThread)
{
// The handle is the last one on the pending list, but not the first.
_lastWaitingThread = handle->_prev;
_lastWaitingThread->_next = NULL;
}
else if (handle->_prev != NULL && handle->_next != NULL)
{
// The handle is neither the first one, nor the last one.
handle->_prev->_next = handle->_next;
handle->_next->_prev = handle->_prev;
}
// Now put back in the free list
handle->_next = _freeThreadList;
handle->_prev = NULL;
_freeThreadList = handle;
::unlockMutex(_globalLock);
}
#else
SWItrdMonitor::HandleListItem *SWItrdMonitor::getHandle()
{
HandleListItem *handle = NULL;
::lockMutex(_globalLock);
if (_firstWaitingThread != NULL)
{
handle = _firstWaitingThread;
handle->_count++;
}
else
{
if (_freeThreadList == NULL)
{
handle = new HandleListItem;
// No need to initialize _owner, _next and _prev at this point. They are
// initialized below.
pthread_cond_t *p = new pthread_cond_t;
pthread_cond_init(p, NULL);
handle->_handle = p;
}
else
{
// Take the first event in the free list.
// Altough it should be.
handle = _freeThreadList;
_freeThreadList = handle->_next;
}
_lastWaitingThread = _firstWaitingThread = handle;
handle->_prev = handle->_next = NULL;
handle->_count = 1;
}
::unlockMutex(_globalLock);
return handle;
}
void SWItrdMonitor::resetHandle(HandleListItem *handle)
{
::lockMutex(_globalLock);
// Remove from the pending list if not already removed.
if (--handle->_count == 0)
{
_firstWaitingThread = _lastWaitingThread = NULL;
// Now put back in the free list
handle->_next = _freeThreadList;
handle->_prev = NULL;
_freeThreadList = handle;
}
::unlockMutex(_globalLock);
}
#endif // _WIN32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -