// ********************************************************************** // // Copyright (c) 2000 // Object Oriented Concepts, Inc. // Billerica, MA, USA // // All Rights Reserved // // ********************************************************************** #include #include #include #include #include #include #include #include #include #ifdef HAVE_STD_IOSTREAM using namespace std; #endif // // This class encapsulates the functionality of a WIN32 event // semaphore. // // ---------------------------------------------------------------------- // JTCEvent constructor and destructor // ---------------------------------------------------------------------- JTCEvent::JTCEvent() #ifndef WIN32 : posted_(false) #endif { #if defined(HAVE_POSIX_THREADS) JTC_SYSCALL_2(pthread_cond_init, &cond_, 0, != 0) #endif #if defined(HAVE_DCE_THREADS) JTC_SYSCALL_2(pthread_cond_init, &cond_, pthread_condattr_default, != 0) #endif #if defined(HAVE_WIN32_THREADS) JTC_SYSCALL_4(event_ = CreateEvent, 0, 1, 0, 0, == INVALID_HANDLE_VALUE) #endif } JTCEvent::~JTCEvent() { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) pthread_cond_destroy(&cond_); #endif #if defined(HAVE_WIN32_THREADS) CloseHandle(event_); #endif } // ---------------------------------------------------------------------- // JTCEvent public member implementation // ---------------------------------------------------------------------- // // Set the state of the event object to signalled. Wake any waiting // threads. // void JTCEvent::post() { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) JTCSynchronized sync(mut_); posted_ = true; // // Wake up all waiters. // JTC_SYSCALL_1(pthread_cond_broadcast, &cond_, != 0) #endif #if defined(HAVE_WIN32_THREADS) JTC_SYSCALL_1(SetEvent, event_, == 0) #endif } // // Wake any waiting threads. // void JTCEvent::pulse() { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) JTCSynchronized sync(mut_); posted_ = false; // // Wake up one waiter. // JTC_SYSCALL_1(pthread_cond_signal, &cond_, != 0) #endif #if defined(HAVE_WIN32_THREADS) JTC_SYSCALL_1(PulseEvent, event_, == 0) #endif } // // Wait for the event object to become signalled. // void JTCEvent::wait() { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) // // We want to lock the internal mutex. If we're not currently // posted then wait on the condition variable. next unlock the // internal mutex, // JTCSynchronized sync(mut_); if(!posted_) { for(;;) { try { JTC_SYSCALL_2(pthread_cond_wait, &cond_, &mut_.lock_, < 0) } catch(const JTCSystemCallException& e) { if(e.getError() == EINTR) continue; throw; } break; } } #endif #if defined(HAVE_WIN32_THREADS) JTC_SYSCALL_2(WaitForSingleObject,event_, INFINITE, != WAIT_OBJECT_0) #endif } // // Set the state of the event object to unsignalled. // void JTCEvent::reset() { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) JTCSynchronized sync(mut_); posted_ = false; #endif #if defined(HAVE_WIN32_THREADS) JTC_SYSCALL_1(ResetEvent, event_, == 0) #endif } // // Determine if the event object is signalled. // bool JTCEvent::posted() { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) JTCSynchronized sync(mut_); return posted_; #endif #if defined(HAVE_WIN32_THREADS) long rc; JTC_SYSCALL_2(rc = WaitForSingleObject, event_, 0, == WAIT_FAILED) return rc != WAIT_TIMEOUT; #endif }