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

📄 switrdmonitor.cpp

📁 openvxi3.4是一个voicexml对话脚本语言的解释器源码.可用VC6.0编译.
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    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 + -