📄 tlibbe.cxx
字号:
} if ( result == B_OK ) { // thread is dead return 1; } if ( result == B_BAD_THREAD_ID ) { // thread has invalid id return 1; } return 0; // ???}PThreadIdentifier PThread::GetCurrentThreadId(void){ return ::find_thread(NULL);}int PThread::PXBlockOnIO(int handle, int type, const PTimeInterval & timeout){ PTRACE(7, "PWLib\tPThread::PXBlockOnIO(" << handle << ',' << type << ')'); if ((handle < 0) || (handle >= PProcess::Current().GetMaxHandles())) { PTRACE(2, "PWLib\tAttempt to use illegal handle in PThread::PXBlockOnIO, handle=" << handle); errno = EBADF; return -1; } // make sure we flush the buffer before doing a write P_fd_set read_fds; P_fd_set write_fds; P_fd_set exception_fds; int retval; do { switch (type) { case PChannel::PXReadBlock: case PChannel::PXAcceptBlock: read_fds = handle; write_fds.Zero(); exception_fds.Zero(); break; case PChannel::PXWriteBlock: read_fds.Zero(); write_fds = handle; exception_fds.Zero(); break; case PChannel::PXConnectBlock: read_fds.Zero(); write_fds = handle; exception_fds = handle; break; default: PAssertAlways(PLogicError); return 0; } // include the termination pipe into all blocking I/O functions read_fds += unblockPipe[0]; P_timeval tval = timeout; retval = ::select(PMAX(handle, unblockPipe[0])+1, read_fds, write_fds, exception_fds, tval); } while (retval < 0 && errno == EINTR); if ((retval == 1) && read_fds.IsPresent(unblockPipe[0])) { BYTE ch; ::read(unblockPipe[0], &ch, 1); errno = EINTR; retval = -1; PTRACE(6, "PWLib\tUnblocked I/O"); } return retval;}void PThread::PXAbortBlock(void) const{ BYTE ch; ::write(unblockPipe[1], &ch, 1);}///////////////////////////////////////////////////////////////////////////////// PProcessPDECLARE_CLASS(PHouseKeepingThread, PThread) public: PHouseKeepingThread() : PThread(1000, NoAutoDeleteThread, NormalPriority, "Housekeeper") { closing = FALSE; Resume(); } void Main(); void SetClosing() { closing = TRUE; } protected: BOOL closing;};void PProcess::Construct(){ maxHandles = FOPEN_MAX; PTRACE(4, "PWLib\tMaximum per-process file handles is " << maxHandles); ::pipe(timerChangePipe); // initialise the housekeeping thread housekeepingThread = NULL; CommonConstruct();}void PHouseKeepingThread::Main(){ PProcess & process = PProcess::Current(); while (!closing) { PTimeInterval delay = process.timers.Process(); int fd = process.timerChangePipe[0]; P_fd_set read_fds = fd; P_timeval tval = delay; if (::select(fd+1, read_fds, NULL, NULL, tval) == 1) { BYTE ch; ::read(fd, &ch, 1); } process.PXCheckSignals(); } }void PProcess::SignalTimerChange(){ if (housekeepingThread == NULL) { housekeepingThread = new PHouseKeepingThread; } BYTE ch; write(timerChangePipe[1], &ch, 1);}BOOL PProcess::SetMaxHandles(int newMax){ return FALSE;}PProcess::~PProcess(){ PreShutdown(); // Don't wait for housekeeper to stop if Terminate() is called from it. if (housekeepingThread != NULL && PThread::Current() != housekeepingThread) { housekeepingThread->SetClosing(); SignalTimerChange(); housekeepingThread->WaitForTermination(); delete housekeepingThread; } CommonDestruct();}///////////////////////////////////////////////////////////////////////////////// PSemaphorePSemaphore::PSemaphore(BOOL fNested) : mfNested(fNested){}PSemaphore::PSemaphore(unsigned initial, unsigned){ Create(initial);} void PSemaphore::Create(unsigned initial){ mOwner = ::find_thread(NULL); PAssertOS(mOwner != B_BAD_THREAD_ID); if(!mfNested) { mCount = initial; semId = ::create_sem(initial, "PWLS"); PAssertOS(semId >= B_NO_ERROR); #ifdef DEBUG_SEMAPHORES sem_info info; get_sem_info(semId, &info); PError << "::create_sem (PSemaphore()), id: " << semId << ", this: " << this << ", count:" << info.count << endl; #endif } else // Use BLocker { semId = (sem_id) new BLocker("PWLN", true); // PWLib use recursive locks. true for benaphore style, false for not }}PSemaphore::~PSemaphore(){ if(!mfNested) { status_t result = B_NO_ERROR; PAssertOS(semId >= B_NO_ERROR); // Transmit ownership of the semaphore to our thread thread_id curThread = ::find_thread(NULL); if(mOwner != curThread) { thread_info tinfo; ::get_thread_info(curThread, &tinfo); ::set_sem_owner(semId, tinfo.team); mOwner = curThread; } #ifdef DEBUG_SEMAPHORES sem_info info; get_sem_info(semId, &info); PError << "::delete_sem, id: " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count; #endif // Deleting the semaphore id result = ::delete_sem(semId); #ifdef DEBUG_SEMAPHORES if( result != B_NO_ERROR ) PError << "...delete_sem failed, error: " << strerror(result) << endl; #endif } else // Use BLocker { delete (BLocker*) semId; // Thanks! }}void PSemaphore::Wait(){ if(!mfNested) { PAssertOS(semId >= B_NO_ERROR); status_t result = B_NO_ERROR; #ifdef DEBUG_SEMAPHORES sem_info info; get_sem_info(semId, &info); PError << "::acquire_sem, id: " << semId << ", name: " << info.name << ", count:" << info.count << endl; #endif while((B_BAD_THREAD_ID != mOwner) && ((result = ::acquire_sem(semId)) == B_INTERRUPTED)) { } } else { ((BLocker*)semId)->Lock(); // Using class to support recursive locks }}BOOL PSemaphore::Wait(const PTimeInterval & timeout){ PInt64 ms = timeout.GetMilliSeconds(); bigtime_t microseconds = ms * 1000; status_t result = B_NO_ERROR; if(!mfNested) { PAssertOS(semId >= B_NO_ERROR); PAssertOS(timeout < PMaxTimeInterval); #ifdef DEBUG_SEMAPHORES sem_info info; get_sem_info(semId, &info); PError << "::acquire_sem_etc " << semId << ",this: " << this << ", name: " << info.name << ", count:" << info.count << ", ms: " << microseconds << endl; #endif while((B_BAD_THREAD_ID != mOwner) && ((result = ::acquire_sem_etc(semId, 1, B_RELATIVE_TIMEOUT, microseconds)) == B_INTERRUPTED)) { } } else { result = ((BLocker*)semId)->LockWithTimeout(microseconds); // Using BLocker class to support recursive locks } return ms == 0 ? FALSE : result == B_OK;}void PSemaphore::Signal(){ if(!mfNested) { PAssertOS(semId >= B_NO_ERROR); #ifdef DEBUG_SEMAPHORES sem_info info; get_sem_info(semId, &info); PError << "::release_sem " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count << endl; #endif ::release_sem(semId); } else { ((BLocker*)semId)->Unlock(); // Using BLocker class to support recursive locks } }BOOL PSemaphore::WillBlock() const{ if(!mfNested) { PAssertOS(semId >= B_NO_ERROR); #ifdef DEBUG_SEMAPHORES sem_info info; get_sem_info(semId, &info); PError << "::acquire_sem_etc (WillBlock) " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count << endl; #endif status_t result = ::acquire_sem_etc(semId, 0, B_RELATIVE_TIMEOUT, 0); return result == B_WOULD_BLOCK; } else { return mOwner == find_thread(NULL); // If we are in our own thread, we won't lock }}///////////////////////////////////////////////////////////////////////////////// PSyncPointPSyncPoint::PSyncPoint() : PSemaphore(FALSE) // FALSE is semaphore based, TRUE means implemented through BLocker{ PSemaphore::Create(0);}void PSyncPoint::Signal(){ PSemaphore::Signal();} void PSyncPoint::Wait(){ PSemaphore::Wait();} BOOL PSyncPoint::Wait(const PTimeInterval & timeout){ return PSemaphore::Wait(timeout);} BOOL PSyncPoint::WillBlock() const{ return PSemaphore::WillBlock();}//////////////////////////////////////////////////////////////////////////////// PMutex, derived from BLightNestedLocker PMutex::PMutex() : PSemaphore(TRUE) // TRUE means implemented through BLocker{ PSemaphore::Create(0);}PMutex::PMutex(const PMutex&) : PSemaphore(TRUE){ PAssertAlways("PMutex copy constructor not supported");} void PMutex::Signal(){ PSemaphore::Signal();} void PMutex::Wait(){ PSemaphore::Wait();} BOOL PMutex::Wait(const PTimeInterval & timeout){ return PSemaphore::Wait(timeout);} BOOL PMutex::WillBlock() const{ return PSemaphore::WillBlock();}//////////////////////////////////////////////////////////////////////////////// Extra functionality not found in BeOSint seteuid(uid_t uid) { return 0; }int setegid(gid_t gid) { return 0; }///////////////////////////////////////////////////////////////////////////////// Toolchain dependent stuff#if (__GNUC_MINOR__ > 9)#warning "Using gcc 2.95.x" ostream& ostream::write(const char *s, streamsize n) { return write(s, (long) n); }; istream& istream::read(char *s, streamsize n) { return read(s, (long) n); };#endif // gcc minor > 9 // End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -