Uncommented beaudio code
[pwlib.git] / src / ptlib / unix / tlibbe.cxx
blob69128078f3f56afc954ffd9a1ec370fe8c2193bd
1 /*
2 * tlibbe.cxx
4 * Thread library implementation for BeOS
6 * Portable Windows Library
8 * The contents of this file are subject to the Mozilla Public License
9 * Version 1.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15 * the License for the specific language governing rights and limitations
16 * under the License.
18 * The Original Code is Portable Windows Library.
20 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
22 * Portions are Copyright (c) 1993-1998 Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): Yuri Kiryanov, ykiryanov at users.sourceforge.net
29 * $Log$
30 * Revision 1.21 2004/04/02 03:17:19 ykiryanov
31 * New version, improved
33 * Revision 1.20 2004/02/23 23:40:42 ykiryanov
34 * Added missing constructor for PMutex
36 * Revision 1.19 2004/02/23 21:23:09 ykiryanov
37 * Removed assert line to enable semaphore constructor
39 * Revision 1.18 2004/02/23 20:37:17 ykiryanov
40 * Changed function definition PXBlockIO to prototype one
42 * Revision 1.17 2004/02/23 18:10:39 ykiryanov
43 * Added a parameter to semaphore constructor to avoid ambiguity
45 * Revision 1.16 2004/02/23 00:02:20 ykiryanov
46 * Changed my e-mail to ykiryanov at users.sourceforge.net. Just in case someone wants to collaborate
48 * Revision 1.15 2004/02/22 23:59:28 ykiryanov
49 * Added missing functions: PProcess::SetMaxHandles(), PThread::GetCurrentThreadId(),
50 * PThread::PXAbortBlock(), PSyncPoint::Signal(), ::Wait(), ::Wait(timeout), ::WillBlock()
52 * Revision 1.14 2004/02/22 04:35:04 ykiryanov
53 * Removed PMutex desctructor
55 * Revision 1.13 2003/02/26 01:13:18 robertj
56 * Fixed race condition where thread can terminatebefore an IsSuspeded() call
57 * occurs and cause an assert, thanks Sebastian Meyer
59 * Revision 1.12 2001/06/30 06:59:07 yurik
60 * Jac Goudsmit from Be submit these changes 6/28. Implemented by Yuri Kiryanov
62 * Revision 1.11 2001/03/07 06:57:32 yurik
63 * Changed email to current one
65 * Revision 1.10 2001/01/16 12:32:06 rogerh
66 * Remove duplicate SetAutoDelete() function. Submitted by
67 * Jac Goudsmit <jac_goudsmit@yahoo.com>
72 class PProcess;
73 class PSemaphore;
75 #include <ptlib.h>
77 //#define DEBUG_SEMAPHORES
78 //#define DEBUG_THREADS
80 ///////////////////////////////////////////////////////////////////////////////
81 // Threads
83 static int const priorities[] = {
84 1, // Lowest priority is 1. 0 is not
85 B_LOW_PRIORITY,
86 B_NORMAL_PRIORITY,
87 B_DISPLAY_PRIORITY,
88 B_URGENT_DISPLAY_PRIORITY,
91 int32 PThread::ThreadFunction(void * threadPtr)
93 PThread * thread = (PThread *)PAssertNULL(threadPtr);
95 PProcess & process = PProcess::Current();
97 process.activeThreadMutex.Wait();
98 process.activeThreads.SetAt(thread->threadId, thread);
99 process.activeThreadMutex.Signal();
101 process.SignalTimerChange();
103 thread->Main();
105 return 0;
108 PThread::PThread()
109 : threadId(B_BAD_THREAD_ID),
110 priority(B_NORMAL_PRIORITY),
111 originalStackSize(0)
115 PThread::PThread(PINDEX stackSize,
116 AutoDeleteFlag deletion,
117 Priority priorityLevel,
118 const PString & name)
119 : threadName(name)
121 PAssert(stackSize > 0, PInvalidParameter);
122 autoDelete = deletion == AutoDeleteThread;
123 originalStackSize = stackSize;
125 priority = priorities[priorityLevel];
127 PString str("PWLT");
128 str += threadName;
129 #ifdef DEBUG_THREADS
130 PError << "::spawn_thread(" << str << "), priority:" << priority << endl;
131 #endif
133 threadId = ::spawn_thread(ThreadFunction, // Function
134 (const char*) str, // Name
135 priority, // Priority
136 (void *) this); // Pass this as cookie
138 PAssertOS(threadId >= B_NO_ERROR);
140 #ifdef DEBUG_THREADS
141 PError << ", id: " << threadId << endl;
142 #endif
144 ::pipe(unblockPipe);
146 if (autoDelete)
148 PProcess & process = PProcess::Current();
149 process.deleteThreadMutex.Wait();
150 process.autoDeleteThreads.Append(this);
151 process.deleteThreadMutex.Signal();
156 PThread::~PThread()
158 if (originalStackSize <= 0)
159 return;
161 PProcess & process = PProcess::Current();
162 process.activeThreadMutex.Wait();
163 process.activeThreads.SetAt(threadId, NULL);
164 process.activeThreadMutex.Signal();
166 if (!IsTerminated())
167 Terminate();
169 ::close(unblockPipe[0]);
170 ::close(unblockPipe[1]);
174 void PThread::Restart()
176 PAssert(IsTerminated(), "Cannot restart running thread");
178 PString str("PWLT");
179 str += threadName;
180 #ifdef DEBUG_THREADS
181 PError << "::spawn_thread(" << str << "), priority:" << priority << endl;
182 #endif
184 threadId = ::spawn_thread(ThreadFunction, // Function
185 (const char*) str, // Name
186 priority,
187 (void *) this); // Pass this as cookie
189 #ifdef DEBUG_THREADS
190 PError << ", id: " << threadId << endl;
191 #endif
193 PAssertOS(threadId >= B_NO_ERROR);
197 void PThread::Terminate()
199 PAssert(!IsTerminated(), "Operation on terminated thread");
200 PAssert(originalStackSize > 0, PLogicError);
202 if (Current() == this)
204 sem_id semId = ::create_sem( 1, "PWST" );
205 if ( ::acquire_sem(semId) == B_NO_ERROR )
207 // Invalidate the thread
208 threadId = B_BAD_THREAD_ID;
209 ::release_sem(semId);
210 ::delete_sem(semId);
212 #ifdef DEBUG_THREADS
213 PError << "::exit_thread(0), id:" << threadId << endl;
214 #endif
215 ::exit_thread(0);
218 else
220 sem_id semId = ::create_sem( 1, "PWTS" );
221 if ( ::acquire_sem(semId) == B_NO_ERROR )
223 thread_id idToKill;
224 idToKill = threadId;
226 // Invalidate the thread
227 threadId = B_BAD_THREAD_ID;
229 // Kill it
230 if (idToKill != B_BAD_THREAD_ID)
232 ::release_sem(semId);
233 ::delete_sem(semId);
235 #ifdef DEBUG_THREADS
236 PError << "::kill_thread(" << idToKill << ")" << endl;
237 #endif
238 ::kill_thread(idToKill);
242 PAssert(threadId == B_BAD_THREAD_ID, "Can't acquire semaphore to terminate thread");
246 BOOL PThread::IsTerminated() const
248 return threadId == B_BAD_THREAD_ID;
252 void PThread::WaitForTermination() const
254 WaitForTermination(PMaxTimeInterval);
258 BOOL PThread::WaitForTermination(const PTimeInterval & /*maxWait*/) const // Fix timeout
260 status_t result = B_NO_ERROR;
261 status_t exit_value = B_NO_ERROR;
263 #ifdef DEBUG_THREADS
264 PError << "::wait_for_thread(" << threadId << "), result:";
265 #endif
267 result = ::wait_for_thread(threadId, &exit_value);
268 if ( result == B_INTERRUPTED ) { // thread was killed.
269 #ifdef DEBUG_THREADS
270 PError << "B_INTERRUPTED" << endl;
271 #endif
272 return TRUE;
275 if ( result == B_OK ) { // thread is dead
276 #ifdef DEBUG_THREADS
277 PError << "B_OK" << endl;
278 #endif
279 return TRUE;
282 if ( result == B_BAD_THREAD_ID ) { // thread has invalid id
283 #ifdef DEBUG_THREADS
284 PError << "B_BAD_THREAD_ID" << endl;
285 #endif
286 return TRUE;
289 return FALSE;
293 void PThread::Suspend(BOOL susp)
295 PAssert(!IsTerminated(), "Operation on terminated thread");
296 if (susp)
298 status_t result = ::suspend_thread(threadId);
300 PAssert(result == B_OK, "Thread don't want to be suspended");
302 else
303 Resume();
307 void PThread::Resume()
309 PAssert(!IsTerminated(), "Operation on terminated thread");
310 status_t result = ::resume_thread(threadId);
312 PAssert(result == B_NO_ERROR, "Thread doesn't want to resume");
316 BOOL PThread::IsSuspended() const
318 thread_info info;
319 status_t result = ::get_thread_info(threadId, &info);
321 PAssert(result == B_OK && threadId == info.thread, "Thread info inaccessible");
322 return info.state == B_THREAD_SUSPENDED;
325 void PThread::SetAutoDelete(AutoDeleteFlag deletion)
327 PAssert(deletion != AutoDeleteThread || this != &PProcess::Current(), PLogicError);
328 autoDelete = deletion == AutoDeleteThread;
331 void PThread::SetPriority(Priority priorityLevel)
333 PAssert(!IsTerminated(), "Operation on terminated thread");
335 priority = priorities[priorityLevel];
336 status_t result = ::set_thread_priority(threadId, priority );
338 PAssert(result == B_OK, "Thread priority change error");
342 PThread::Priority PThread::GetPriority() const
344 PAssert(!IsTerminated(), "Operation on terminated thread");
346 switch (priority) {
347 case 0 :
348 return LowestPriority;
349 case B_LOW_PRIORITY :
350 return LowPriority;
351 case B_NORMAL_PRIORITY :
352 return NormalPriority;
353 case B_DISPLAY_PRIORITY :
354 return HighPriority;
355 case B_URGENT_DISPLAY_PRIORITY :
356 return HighestPriority;
358 PAssertAlways(POperatingSystemError);
359 return LowestPriority;
362 void PThread::Yield()
364 // we just sleep for long enough to cause a reschedule (100 microsec)
365 ::snooze(100);
368 void PThread::Sleep( const PTimeInterval & delay ) // Time interval to sleep for.
370 bigtime_t microseconds =
371 delay == PMaxTimeInterval ? B_INFINITE_TIMEOUT : (delay.GetMilliSeconds() * 1000 );
373 status_t result = ::snooze( microseconds ) ; // delay in ms, snooze in microsec
374 PAssert(result == B_OK, "Thread has insomnia");
377 void PThread::InitialiseProcessThread()
379 originalStackSize = 0;
380 autoDelete = FALSE;
382 ::pipe(unblockPipe);
384 threadId = ::find_thread(NULL);
385 PAssertOS(threadId >= B_NO_ERROR);
387 ((PProcess *)this)->activeThreads.DisallowDeleteObjects();
388 ((PProcess *)this)->activeThreads.SetAt(threadId, this);
392 PThread * PThread::Current()
394 PProcess & process = PProcess::Current();
395 process.activeThreadMutex.Wait();
397 thread_id tId = ::find_thread(NULL);
398 PAssertOS(tId >= B_NO_ERROR);
400 PThread * thread = process.activeThreads.GetAt( tId );
402 process.activeThreadMutex.Signal();
403 return thread;
406 int PThread::PXBlockOnChildTerminate(int pid, const PTimeInterval & /*timeout*/) // Fix timeout
408 status_t result = B_NO_ERROR;
409 status_t exit_value = B_NO_ERROR;
411 #ifdef DEBUG_THREADS
412 PError << "::wait_for_thread(" << pid << "), result:";
413 #endif
415 result = ::wait_for_thread(pid, &exit_value);
416 if ( result == B_INTERRUPTED )
418 // thread was killed.
419 #ifdef DEBUG_THREADS
420 PError << "B_INTERRUPTED" << endl;
421 #endif
422 return 1;
425 if ( result == B_OK )
427 // thread is dead
428 #ifdef DEBUG_THREADS
429 PError << "B_OK" << endl;
430 #endif
431 return 1;
434 if ( result == B_BAD_THREAD_ID )
436 // thread has invalid id
437 #ifdef DEBUG_THREADS
438 PError << "B_BAD_THREAD_ID" << endl;
439 #endif
440 return 1;
443 return 0; // ???
446 PThreadIdentifier PThread::GetCurrentThreadId(void)
448 return ::find_thread(NULL);
451 int PThread::PXBlockOnIO(int handle, int type, const PTimeInterval & timeout)
453 // make sure we flush the buffer before doing a write
454 fd_set tmp_rfd, tmp_wfd, tmp_efd;
455 fd_set * read_fds = &tmp_rfd;
456 fd_set * write_fds = &tmp_wfd;
457 fd_set * exception_fds = &tmp_efd;
459 struct timeval * tptr = NULL;
460 struct timeval timeout_val;
461 if (timeout != PMaxTimeInterval) { // Clean up for infinite timeout
462 static const PTimeInterval oneDay(0, 0, 0, 0, 1);
463 if (timeout < oneDay) {
465 timeout_val.tv_usec = (timeout.GetMilliSeconds() % 1000) * 1000;
466 timeout_val.tv_sec = timeout.GetSeconds();
467 tptr = &timeout_val;
471 int retval;
473 for (;;)
475 FD_ZERO (read_fds);
476 FD_ZERO (write_fds);
477 FD_ZERO (exception_fds);
479 switch (type) {
480 case PChannel::PXReadBlock:
481 case PChannel::PXAcceptBlock:
482 FD_SET (handle, read_fds);
483 break;
484 case PChannel::PXWriteBlock:
485 FD_SET (handle, write_fds);
486 break;
487 case PChannel::PXConnectBlock:
488 FD_SET (handle, write_fds);
489 FD_SET (handle, exception_fds);
490 break;
491 default:
492 PAssertAlways(PLogicError);
493 return 0;
495 } // switch(type)
497 // include the termination pipe into all blocking I/O functions
498 int width = handle+1;
499 FD_SET(unblockPipe[0], read_fds);
500 width = PMAX(width, unblockPipe[0]+1);
502 retval = ::select(width, read_fds, write_fds, exception_fds, tptr);
504 if ((retval >= 0) || (errno != EINTR))
505 break;
506 } // end for (;;)
508 if ((retval == 1) && FD_ISSET(unblockPipe[0], read_fds))
510 BYTE ch;
511 ::read(unblockPipe[0], &ch, 1);
512 errno = EINTR;
513 retval = -1;
514 //PTRACE(1,"Unblocked I/O");
517 return retval;
520 int PThread::PXBlockOnIO(int maxHandles,
521 fd_set * readBits,
522 fd_set * writeBits,
523 fd_set * exceptionBits,
524 const PTimeInterval & timeout,
525 const PIntArray & /*osHandles*/)
527 struct timeval * tptr = NULL;
528 struct timeval timeout_val;
529 if (timeout != PMaxTimeInterval)
531 // Clean up for infinite timeout
532 static const PTimeInterval oneDay(0, 0, 0, 0, 1);
533 if (timeout < oneDay) {
534 timeout_val.tv_usec = (timeout.GetMilliSeconds() % 1000) * 1000;
535 timeout_val.tv_sec = timeout.GetSeconds();
536 tptr = &timeout_val;
540 int retval = ::select(maxHandles, readBits, writeBits, exceptionBits, tptr);
541 PProcess::Current().PXCheckSignals();
542 return retval;
545 void PThread::PXAbortBlock(void) const
547 BYTE ch;
548 ::write(unblockPipe[1], &ch, 1);
551 ///////////////////////////////////////////////////////////////////////////////
552 // PProcess
553 PDECLARE_CLASS(PHouseKeepingThread, PThread)
554 public:
555 PHouseKeepingThread()
556 : PThread(1000, NoAutoDeleteThread, NormalPriority, "Housekeeper")
557 { closing = FALSE; Resume(); }
559 void Main();
560 void SetClosing() { closing = TRUE; }
562 protected:
563 BOOL closing;
566 void PProcess::Construct()
568 ::pipe(timerChangePipe);
570 // initialise the housekeeping thread
571 housekeepingThread = NULL;
573 CommonConstruct();
576 void PHouseKeepingThread::Main()
578 debugger("Housekeeper");
580 PProcess & process = PProcess::Current();
582 while (!closing) {
583 PTimeInterval delay = process.timers.Process();
585 int fd = process.timerChangePipe[0];
587 fd_set tmp_rfd;
588 fd_set * read_fds = &tmp_rfd;
590 FD_ZERO(read_fds);
591 FD_SET(fd, read_fds);
593 static const PTimeInterval oneDay(0, 0, 0, 0, 1);
594 struct timeval * tptr = NULL;
595 timeval tval;
596 if (delay < oneDay) {
597 tval.tv_usec = (delay.GetMilliSeconds() % 1000) * 1000;
598 tval.tv_sec = delay.GetSeconds();
599 tptr = &tval;
601 if (::select(fd+1, read_fds, NULL, NULL, tptr) == 1) {
602 BYTE ch;
603 ::read(fd, &ch, 1);
606 process.PXCheckSignals();
610 void PProcess::SignalTimerChange()
612 if (housekeepingThread == NULL) {
613 housekeepingThread = new PHouseKeepingThread;
616 BYTE ch;
617 write(timerChangePipe[1], &ch, 1);
620 BOOL PProcess::SetMaxHandles(int)
622 return TRUE;
625 PProcess::~PProcess()
627 // Don't wait for housekeeper to stop if Terminate() is called from it.
628 if (housekeepingThread != NULL && PThread::Current() != housekeepingThread) {
629 housekeepingThread->SetClosing();
630 SignalTimerChange();
631 housekeepingThread->WaitForTermination();
632 delete housekeepingThread;
634 CommonDestruct();
637 ///////////////////////////////////////////////////////////////////////////////
638 // PSemaphore
640 PSemaphore::PSemaphore(unsigned initial, unsigned maxCount)
641 : mOwner(::find_thread(NULL)), semId(::create_sem(initial, "PWLS")), mCount(initial)
643 PAssertOS(semId >= B_NO_ERROR);
644 PAssertOS(mOwner != B_BAD_THREAD_ID);
646 #ifdef DEBUG_SEMAPHORES
647 sem_info info;
648 get_sem_info(semId, &info);
649 PError << "::create_sem (PSemaphore(i,m)), id: " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count << endl;
650 #endif
654 PSemaphore::~PSemaphore()
656 status_t result = B_NO_ERROR;
657 PAssertOS(semId >= B_NO_ERROR);
659 // Transmit ownership of the semaphore to our thread
660 thread_id curThread = ::find_thread(NULL);
661 if(mOwner != curThread)
663 thread_info tinfo;
664 ::get_thread_info(curThread, &tinfo);
665 ::set_sem_owner(semId, tinfo.team);
666 mOwner = curThread;
669 #ifdef DEBUG_SEMAPHORES
670 sem_info info;
671 get_sem_info(semId, &info);
672 PError << "::delete_sem, id: " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count;
673 #endif
675 // Deleting the semaphore id
676 result = ::delete_sem(semId);
678 #ifdef DEBUG_SEMAPHORES
679 if( result != B_NO_ERROR )
680 PError << "...delete_sem failed, error: " << strerror(result) << endl;
681 #endif
684 void PSemaphore::Wait()
686 PAssertOS(semId >= B_NO_ERROR);
688 status_t result = B_NO_ERROR;
690 #ifdef DEBUG_SEMAPHORES
691 sem_info info;
692 get_sem_info(semId, &info);
693 PError << "::acquire_sem_etc, id: " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count;
694 #endif
696 while ((B_BAD_THREAD_ID != mOwner)
697 && ((result = ::acquire_sem(semId)) == B_INTERRUPTED))
701 #ifdef DEBUG_SEMAPHORES
702 if( result != B_NO_ERROR )
703 PError << "... failed, error: " << strerror(result);
705 PError << endl;
706 #endif
709 BOOL PSemaphore::Wait(const PTimeInterval & timeout)
711 PAssertOS(semId >= B_NO_ERROR);
713 status_t result = B_NO_ERROR;
715 PInt64 ms = timeout.GetMilliSeconds();
716 bigtime_t microseconds =
717 ms? timeout == PMaxTimeInterval ? B_INFINITE_TIMEOUT : ( ms * 1000 ) : 0;
719 #ifdef DEBUG_SEMAPHORES
720 sem_info info;
721 get_sem_info(semId, &info);
722 PError << "::acquire_sem_etc " << semId << ",this: " << this << ", name: " << info.name << ", count:" << info.count << ", timeout:";
724 if( microseconds == B_INFINITE_TIMEOUT )
725 PError << "infinite";
726 else
727 PError << microseconds << " ms";
728 #endif
730 while((B_BAD_THREAD_ID != mOwner)
731 && ((result = ::acquire_sem_etc(semId, 1,
732 B_RELATIVE_TIMEOUT, microseconds)) == B_INTERRUPTED))
736 #ifdef DEBUG_SEMAPHORES
737 if( result != B_NO_ERROR )
738 PError << " ... failed! error: " << strerror(result);
740 PError << " " << endl;
741 #endif
743 return result == B_TIMED_OUT;
746 void PSemaphore::Signal()
748 PAssertOS(semId >= B_NO_ERROR);
750 #ifdef DEBUG_SEMAPHORES
751 sem_info info;
752 get_sem_info(semId, &info);
753 PError << "::release_sem " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count;
755 status_t result =
756 #endif
757 ::release_sem(semId);
759 #ifdef DEBUG_SEMAPHORES
760 if( result != B_NO_ERROR )
761 PError << "... failed, error: " << strerror(result);
763 PError << endl;
764 #endif
767 BOOL PSemaphore::WillBlock() const
769 PAssertOS(semId >= B_NO_ERROR);
771 status_t result = B_NO_ERROR;
773 #ifdef DEBUG_SEMAPHORES
774 sem_info info;
775 get_sem_info(semId, &info);
776 PError << "::acquire_sem_etc (WillBlock) " << semId << ", this: " << this << ", name: " << info.name << ", count:" << info.count;
777 #endif
779 result = ::acquire_sem_etc(semId, 0, B_RELATIVE_TIMEOUT, 0);
781 #ifdef DEBUG_SEMAPHORES
782 if( result != B_NO_ERROR )
783 PError << "... failed, error: " << strerror(result);
785 PError << endl;
786 #endif
788 return result == B_WOULD_BLOCK;
791 ///////////////////////////////////////////////////////////////////////////////
792 // PMutex
794 PMutex::PMutex()
795 : PSemaphore(1, 1)
797 PAssertOS(semId >= B_NO_ERROR);
798 #ifdef DEBUG_SEMAPHORES
799 sem_info info;
800 get_sem_info(semId, &info);
801 PError << "::create_sem (PMutex()), id: " << semId << " " << ", this: " << this << ", " << info.name << ", count:" << info.count << endl;
802 #endif
805 PMutex::PMutex(const PMutex& m)
806 : PSemaphore(1, 1)
808 PAssertOS(semId >= B_NO_ERROR);
809 #ifdef DEBUG_SEMAPHORES
810 sem_info info;
811 get_sem_info(semId, &info);
812 PError << "::create_sem (PMutex(PMutex)), id: " << semId << " " << ", this: " << this << ", " << info.name << ", count:" << info.count << endl;
813 #endif
816 void PMutex::Wait()
818 PSemaphore::Wait();
821 BOOL PMutex::Wait(const PTimeInterval & timeout)
823 return PSemaphore::Wait(timeout);
826 void PMutex::Signal()
828 PSemaphore::Signal();
831 BOOL PMutex::WillBlock() const
833 return PSemaphore::WillBlock();
836 ///////////////////////////////////////////////////////////////////////////////
837 // PSyncPoint
839 PSyncPoint::PSyncPoint()
840 : PSemaphore(0, 1)
842 PAssertOS(semId >= B_NO_ERROR);
843 #ifdef DEBUG_SEMAPHORES
844 sem_info info;
845 get_sem_info(semId, &info);
846 PError << "::create_sem (PSyncPoint()), id: " << semId << " " << ", this: " << this << info.name << ", count:" << info.count << endl;
847 #endif
850 void PSyncPoint::Signal()
852 PSemaphore::Signal();
855 void PSyncPoint::Wait()
857 PSemaphore::Wait();
860 BOOL PSyncPoint::Wait(const PTimeInterval & timeout)
862 return PSemaphore::Wait(timeout);
865 BOOL PSyncPoint::WillBlock() const
867 return PSemaphore::WillBlock();
870 //////////////////////////////////////////////////////////////////////////////
871 // Extra functionality not found in BeOS
873 int seteuid(uid_t uid) { return 0; }
874 int setegid(gid_t gid) { return 0; }
876 // End Of File ///////////////////////////////////////////////////////////////