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

📄 tlibvx.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
  }
  else
    printf("::SetPriority> Operation on terminated thread\n");
}


PThread::Priority PThread::GetPriority() const
{
  if (!IsTerminated()) {
	int prio;
    if (::taskPriorityGet(PX_threadId, &prio) == OK) {
  switch (prio) {
    case VX_LOWEST_PRIORITY :
      return LowestPriority;
    case VX_LOW_PRIORITY :
      return LowPriority;
    case VX_NORMAL_PRIORITY :
      return NormalPriority;
    case VX_DISPLAY_PRIORITY :
      return HighPriority;
    case VX_URGENT_DISPLAY_PRIORITY :
      return HighestPriority;
        default:
          printf("::GetPriority> Priority %d not mapped\n", prio);
          break;
  }
    }                                               
    else
      printf("::GetPriority> ::taskPriorityGet failed, errno=0x%X\n", errno);
  }
  else
    printf("::GetPriority> Operation on terminated thread\n");

  return LowestPriority;
}

void PThread::Yield()
{
  ::taskDelay(NO_WAIT);
}

void PThread::Sleep( const PTimeInterval & delay ) // Time interval to sleep for in microsec.
{
  ::taskDelay(delay.GetInterval()*sysClkRateGet()/1000);
}

void PThread::InitialiseProcessThread()
{
  originalStackSize = 0;
  autoDelete = FALSE;

  PX_threadId = ::taskIdSelf();
  PAssertOS((PX_threadId != ERROR) && (PX_threadId != 0));

  ((PProcess *)this)->activeThreads.DisallowDeleteObjects();
  ((PProcess *)this)->activeThreads.SetAt(PX_threadId, this);
}


PThread * PThread::Current()
{
  PProcess & process = PProcess::Current();
  process.activeThreadMutex.Wait();
  
  PThread * thread = process.activeThreads.GetAt(::taskIdSelf());

  process.activeThreadMutex.Signal();
  return thread;
}

int PThread::PXBlockOnChildTerminate(int pid, const PTimeInterval & /*timeout*/) // Fix timeout
{
  while (!IsTerminated()) {
    Current()->Sleep(100);
  }
  return TRUE;
}

int PThread::PXBlockOnIO(int handle, int type, const PTimeInterval & timeout)
{
  // make sure we flush the buffer before doing a write
  fd_set tmp_rfd, tmp_wfd, tmp_efd;
  fd_set * read_fds      = &tmp_rfd;
  fd_set * write_fds     = &tmp_wfd;
  fd_set * exception_fds = &tmp_efd;

  FD_ZERO (read_fds);
  FD_ZERO (write_fds);
  FD_ZERO (exception_fds);

  switch (type) {
    case PChannel::PXReadBlock:
    case PChannel::PXAcceptBlock:
      FD_SET (handle, read_fds);
      break;
    case PChannel::PXWriteBlock:
      FD_SET (handle, write_fds);
      break;
    case PChannel::PXConnectBlock:
      FD_SET (handle, write_fds);
      FD_SET (handle, exception_fds);
      break;
    default:
      PAssertAlways(PLogicError);
      return 0;
  }

  P_timeval tval = timeout;
  return ::select(handle+1, read_fds, write_fds, exception_fds, tval);
}

void PThread::PXAbortBlock() const
{
}

///////////////////////////////////////////////////////////////////////////////
// PProcess::HouseKeepingThread

void PProcess::Construct()
{
  // hard coded value, change this to handle more sockets at once with the select call
  maxHandles = 1024; 
  houseKeeper=NULL;
  CommonConstruct();
}

PProcess::HouseKeepingThread::HouseKeepingThread()
  : PThread(10000, NoAutoDeleteThread, HighPriority, PString("HKeeping"))
{
  Resume();
}

void PProcess::HouseKeepingThread::Main()
{
	PProcess & process = PProcess::Current();

	while(1) {
		process.deleteThreadMutex.Wait();
    for (PINDEX i = 0; i < process.autoDeleteThreads.GetSize(); i++) {
			PThread * pThread = (PThread *) process.autoDeleteThreads.GetAt(i);
			if( pThread->IsTerminated() )
				process.autoDeleteThreads.RemoveAt(i--);
			}
		process.deleteThreadMutex.Signal();
		PTimeInterval nextTimer = process.timers.Process();
    if (nextTimer != PMaxTimeInterval) {
			if ( nextTimer.GetInterval() > 10000 )
				nextTimer = 10000;
			}
		breakBlock.Wait( nextTimer );
	}
}

void PProcess::SignalTimerChange()
{
  if (houseKeeper == NULL) {
    // Prevent reentrance before the following assignment is done
    // Placed after above if-statement due to efficiency, and so 
    // requires an another NULL-test.
    CCriticalSection section;
    section.Lock();
  if (houseKeeper == NULL)
     houseKeeper = new HouseKeepingThread;  
    section.Unlock();
  }
  else
    houseKeeper->breakBlock.Signal();
}

///////////////////////////////////////////////////////////////////////////////
// PProcess

PProcess::~PProcess()
{
  PreShutdown();

  Sleep(100);  // Give threads time to die a natural death

  delete houseKeeper;

  // OK, if there are any left we get really insistent...
  activeThreadMutex.Wait();
  for (PINDEX i = 0; i < activeThreads.GetSize(); i++) {
    PThread & thread = activeThreads.GetDataAt(i);
    if (this != &thread && !thread.IsTerminated())
      thread.Terminate();  // With extreme prejudice
  }
  activeThreadMutex.Signal();

  deleteThreadMutex.Wait();
  autoDeleteThreads.RemoveAll();
  deleteThreadMutex.Signal();

  delete configFiles;
}

///////////////////////////////////////////////////////////////////////////////
// PSemaphore

PSemaphore::PSemaphore(SEM_ID anId)
{
  initialVar = 1;
  maxCountVar = UINT_MAX;
  semId = anId;
  PAssertOS(semId != NULL);
}

PSemaphore::PSemaphore(unsigned initial, unsigned maxCount)
{
  if (initial > maxCount)
    initial = maxCount;
  initialVar = initial;
  maxCountVar = maxCount;
  semId = ::semCCreate(SEM_Q_FIFO, initial);
  PAssertOS(semId != NULL);
}

PSemaphore::PSemaphore(const PSemaphore & sem)
{
  initialVar = sem.GetInitial();
  maxCountVar = sem.GetMaxCount();

  if (initialVar > maxCountVar)
    initialVar = maxCountVar;
  semId = ::semCCreate(SEM_Q_FIFO, initialVar);
  PAssertOS(semId != NULL);
}

PSemaphore::~PSemaphore()
	{
  if (semId != NULL) {
    if (::semDelete(semId) == OK)
      semId = NULL;
    else
      printf("~PSemaphore> Error delete with ID=0x%X with errno: 0x%X\n", 
             (unsigned int)semId, errno);
	}
}

void PSemaphore::Wait()
{
  STATUS result = ::semTake(semId, WAIT_FOREVER);
  if (result == OK) {
    CCriticalSection section;
    section.Lock();
    initialVar--;
    section.Unlock();
  }
	PAssertOS(result != ERROR);
}


BOOL PSemaphore::Wait(const PTimeInterval & timeout)
{
  long wait;
	if (timeout == PMaxTimeInterval) {
		wait = WAIT_FOREVER;
	}
	else {
	 int ticks = sysClkRateGet();
	 wait = (timeout.GetInterval() * ticks);
 	 wait = wait / 1000;
    wait++; // wait at least one tick
	}
  STATUS result = ::semTake(semId, wait);
  if (result == OK) {
    CCriticalSection section;
    section.Lock();
    initialVar--;
    section.Unlock();
  }
  PAssertOS((result != ERROR) || (errno == S_objLib_OBJ_TIMEOUT));
  return result != ERROR;
}

void PSemaphore::Signal()
{
  CCriticalSection section;
  section.Lock();
  if (initialVar < maxCountVar) {
    section.Unlock();
    STATUS result = ::semGive(semId);
    section.Lock();
    if (result == OK)
      initialVar++;
    PAssertOS(result != ERROR);
  }
  section.Unlock();
}

BOOL PSemaphore::WillBlock() const
{
  return initialVar == 0;
}

///////////////////////////////////////////////////////////////////////////////
// PMutex  
PMutex::PMutex() 
: PSemaphore( ::semMCreate(SEM_Q_FIFO) )
{
}

PMutex::PMutex(const PMutex & mutex)
: PSemaphore(::semMCreate(SEM_Q_FIFO))
{
}

PMutex::~PMutex()
{
  if (semId != NULL) {
    if (::semDelete(semId) == OK)
      semId = NULL;
    else
      printf("~PMutex> Error delete with ID=0x%X with errno: 0x%X\n", 
             (unsigned int)semId, errno);
  }
}

void PMutex::Wait()
{
  STATUS result = ::semTake(semId, WAIT_FOREVER);
	PAssertOS(result == OK);
}

BOOL PMutex::Wait(const PTimeInterval & timeout)
{
  long wait;
	if (timeout == PMaxTimeInterval) {
		wait = WAIT_FOREVER;
	}
	else {
	 int ticks = sysClkRateGet();
	 wait = (timeout.GetMilliSeconds() * ticks);
	 wait = wait / 1000;
    wait++; // wait at least one tick
	}
  STATUS result = ::semTake(semId, wait);
  PAssertOS((result != ERROR) || (errno == S_objLib_OBJ_TIMEOUT));
  return result != ERROR;
}

void PMutex::Signal()
{
	::semGive(semId);
}

BOOL PMutex::WillBlock() const 
{
  STATUS result = ::semTake(semId, NO_WAIT);
  PAssertOS((result != ERROR) || (errno == S_objLib_OBJ_UNAVAILABLE));
  if (result != ERROR)
    ::semGive(semId);
		return result == ERROR;
}

///////////////////////////////////////////////////////////////////////////////
// PSyncPoint

PSyncPoint::PSyncPoint()
  : PSemaphore(0, 1)
{
}

PSyncPoint::PSyncPoint(const PSyncPoint & syncPoint)
  : PSemaphore(syncPoint)
{
}

// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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