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

📄 tlibbe.cxx

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 CXX
📖 第 1 页 / 共 2 页
字号:
 /* * tlibbe.cxx * * Thread library implementation for BeOS * * Portable Windows Library * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): Yuri Kiryanov, BeVox Group, yk@altavista.net. */class PProcess;class PSemaphore;#include <ptlib.h>///////////////////////////////////////////////////////////////////////////////// Threadsstatic int const priorities[] = {  1, // Lowest priority is 1. 0 is not  B_LOW_PRIORITY,  B_NORMAL_PRIORITY,  B_DISPLAY_PRIORITY,  B_URGENT_DISPLAY_PRIORITY,};int32 PThread::ThreadFunction(void * threadPtr){  PThread * thread = (PThread *)PAssertNULL(threadPtr);  PProcess & process = PProcess::Current();  process.activeThreadMutex.Wait();  process.activeThreads.SetAt(thread->threadId, thread);  process.activeThreadMutex.Signal();  process.SignalTimerChange();  thread->Main();  return 0;}PThread::PThread() : threadId(B_BAD_THREAD_ID),   priority(B_NORMAL_PRIORITY),   originalStackSize(0){}PThread::PThread(PINDEX stackSize,                 AutoDeleteFlag deletion,                 Priority priorityLevel,                 const PString & name)  : threadName(name){  PAssert(stackSize > 0, PInvalidParameter);  autoDelete = deletion == AutoDeleteThread;  originalStackSize = stackSize;  priority = priorities[priorityLevel];  threadId =  ::spawn_thread(ThreadFunction, // Function          "PWLT", // Name         priority, // Priority          (void *) this); // Pass this as cookie  PAssertOS(threadId >= B_NO_ERROR);  if (autoDelete) {    PProcess & process = PProcess::Current();    process.deleteThreadMutex.Wait();    process.autoDeleteThreads.Append(this);    process.deleteThreadMutex.Signal();  }}PThread::~PThread(){  if (originalStackSize <= 0)    return;  PProcess & process = PProcess::Current();  process.activeThreadMutex.Wait();  process.activeThreads.SetAt(threadId, NULL);  process.activeThreadMutex.Signal();    if (!IsTerminated())    Terminate();}void PThread::Restart(){  PAssert(IsTerminated(), "Cannot restart running thread");  threadId =  ::spawn_thread(ThreadFunction, // Function          "PWLT", // Name           priority,          (void *) this); // Pass this as cookie           PAssertOS(threadId >= B_NO_ERROR);}void PThread::Terminate(){	PAssert(!IsTerminated(), "Operation on terminated thread");	PAssert(originalStackSize > 0, PLogicError);		if (Current() == this)	{		sem_id semId = ::create_sem( 1, "PWST" );		if ( ::acquire_sem(semId) == B_NO_ERROR )		{			// Invalidate the thread			threadId = B_BAD_THREAD_ID;			::release_sem(semId);			::delete_sem(semId);						::exit_thread(0);		}	}	else 	{		sem_id semId = ::create_sem( 1, "PWTS" );		if ( ::acquire_sem(semId) == B_NO_ERROR )		{			thread_id tId(B_BAD_THREAD_ID);						// Invalidate the thread			tId = threadId;			threadId = B_BAD_THREAD_ID;						// Kill it			if (tId != B_BAD_THREAD_ID)			{				::release_sem(semId);				::delete_sem(semId);				::kill_thread(tId);			}					}	}	PAssert(threadId == B_BAD_THREAD_ID, "Can't acquire semaphore to terminate thread");}BOOL PThread::IsTerminated() const{  return threadId == B_BAD_THREAD_ID;}void PThread::WaitForTermination() const{  WaitForTermination(PMaxTimeInterval);}BOOL PThread::WaitForTermination(const PTimeInterval & /*maxWait*/) const // Fix timeout{  if (threadId == 0)    return TRUE;  status_t result, exit_value;  PINDEX retries = 10;    while ((result = ::wait_for_thread(threadId, &exit_value) != B_NO_ERROR)) {    if ( result == B_INTERRUPTED ) { // thread was killed.      return TRUE;    }    if (retries > 0)      return TRUE;    retries--;  }  return FALSE;}void PThread::Suspend(BOOL susp){  PAssert(!IsTerminated(), "Operation on terminated thread");  if (susp)  {    status_t result = ::suspend_thread(threadId);    PAssert(result == B_OK, "Thread don't want to be suspended");  }  else    Resume();}void PThread::Resume(){  PAssert(!IsTerminated(), "Operation on terminated thread");  status_t result = ::resume_thread(threadId);  PAssert(result == B_NO_ERROR, "Thread doesn't want to resume");}BOOL PThread::IsSuspended() const{  PAssert(!IsTerminated(), "Operation on terminated thread");  thread_info info;  status_t result = ::get_thread_info(threadId, &info);  PAssert(result == B_OK && threadId == info.thread, "Thread info inaccessible");  return info.state == B_THREAD_SUSPENDED;}void PThread::SetPriority(Priority priorityLevel){  PAssert(!IsTerminated(), "Operation on terminated thread");  priority = priorities[priorityLevel];  status_t result = ::set_thread_priority(threadId, priority );  PAssert(result == B_OK, "Thread priority change error");}PThread::Priority PThread::GetPriority() const{  PAssert(!IsTerminated(), "Operation on terminated thread");  switch (priority) {    case 0 :      return LowestPriority;    case B_LOW_PRIORITY :      return LowPriority;    case B_NORMAL_PRIORITY :      return NormalPriority;    case B_DISPLAY_PRIORITY :      return HighPriority;    case B_URGENT_DISPLAY_PRIORITY :      return HighestPriority;  }  PAssertAlways(POperatingSystemError);  return LowestPriority;}void PThread::Yield(){  // we just sleep for long enough to cause a reschedule (100 microsec)  ::snooze(100);}void PThread::Sleep( const PTimeInterval & delay ) // Time interval to sleep for.{	bigtime_t microseconds = 		delay == PMaxTimeInterval ? B_INFINITE_TIMEOUT : (delay.GetMilliSeconds() * 1000 );   status_t result = ::snooze( microseconds ) ; // delay in ms, snooze in microsec  PAssert(result == B_OK, "Thread has insomnia");}void PThread::InitialiseProcessThread(){  originalStackSize = 0;  autoDelete = FALSE;    threadId = ::find_thread(NULL);  PAssertOS(threadId >= B_NO_ERROR);  ((PProcess *)this)->activeThreads.DisallowDeleteObjects();  ((PProcess *)this)->activeThreads.SetAt(threadId, this);}PThread * PThread::Current(){  PProcess & process = PProcess::Current();  process.activeThreadMutex.Wait();    thread_id tId = ::find_thread(NULL);  PAssertOS(tId >= B_NO_ERROR);  PThread * thread = process.activeThreads.GetAt( tId );  process.activeThreadMutex.Signal();  return thread;}int PThread::PXBlockOnChildTerminate(int pid, const PTimeInterval & /*timeout*/) // Fix timeout{  status_t result, exit_value;  while ((result = ::wait_for_thread(pid, &exit_value) != B_NO_ERROR));  return exit_value;}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;  }  struct timeval * tptr = NULL;  struct timeval   timeout_val;  if (timeout != PMaxTimeInterval) { // Clean up for infinite timeout    static const PTimeInterval oneDay(0, 0, 0, 0, 1);    if (timeout < oneDay) {          timeout_val.tv_usec = (timeout.GetMilliSeconds() % 1000) * 1000;      timeout_val.tv_sec  = timeout.GetSeconds();      tptr                = &timeout_val;    }  }  int retval = ::select(handle+1, read_fds, write_fds, exception_fds, tptr);

⌨️ 快捷键说明

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