// ********************************************************************** // // Copyright (c) 2000 // Object Oriented Concepts, Inc. // Billerica, MA, USA // // All Rights Reserved // // ********************************************************************** #ifndef JTC_MUTEX_H #define JTC_MUTEX_H // // This class can be used to establish a critical section. Call the // lock method to lock the mutex, and the unlock Method to unlock the // mutex. If the mutex is currently locked the thread will be // suspended until the mutex becomes unlocked. // class JTCMutex { // // Hide copy constructor and assignment operator. // JTCMutex(const JTCMutex&); void operator=(const JTCMutex&); #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) pthread_mutex_t lock_; // Pthread mutex. #endif #if defined(HAVE_WIN32_THREADS) CRITICAL_SECTION crit_; // WIN32 critical section. #endif friend class JTCEvent; public: JTCMutex() { #if defined(HAVE_POSIX_THREADS) JTC_SYSCALL_2(pthread_mutex_init, &lock_, 0, != 0) #endif #if defined(HAVE_DCE_THREADS) JTC_SYSCALL_2(pthread_mutex_init, &lock_, pthread_mutexattr_default, != 0) #endif #if defined(HAVE_WIN32_THREADS) InitializeCriticalSection(&crit_); #endif } ~JTCMutex() { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) pthread_mutex_destroy(&lock_); #endif #if defined(HAVE_WIN32_THREADS) DeleteCriticalSection(&crit_); #endif } // // Lock the mutex. // void lock() const { #if defined(HAVE_WIN32_THREADS) #endif #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) #if defined(__GNUC__) && defined(__OPTIMIZE__) // // The optimizer for GCC 2.95.1 is broken. The following // three lines of code "fix" the problem. // volatile int i = 1; if (i == 0) ++i; #endif pthread_mutex_t* lock = &((JTCMutex*)this) -> lock_; JTC_SYSCALL_1(pthread_mutex_lock, lock, != 0) #endif #if defined(HAVE_WIN32_THREADS) CRITICAL_SECTION* crit = &((JTCMutex*)this) -> crit_; EnterCriticalSection(crit); #endif } // // Unlock the mutex. // void unlock() const { #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) pthread_mutex_t* lock = &((JTCMutex*)this) -> lock_; JTC_SYSCALL_1(pthread_mutex_unlock, lock, != 0) #endif #if defined(HAVE_WIN32_THREADS) CRITICAL_SECTION* crit = &((JTCMutex*)this) -> crit_; LeaveCriticalSection(crit); #endif } }; // // Unlike the JTCMutex class this mutex can be locked recursively. // That is it can be locked by a thread that already has the mutex // locked. // class JTCRecursiveMutex { // // Hide copy constructor and assignment operator. // JTCRecursiveMutex(const JTCRecursiveMutex&); void operator=(const JTCRecursiveMutex&); // // Internal non-const operations since mutable isn't supported // on some compilers. // void lockI(int count); void unlockI(); // // Lock the mutex count times. // void lock(int count) const; #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS) pthread_mutex_t crit_; // Pthreads mutex. #endif #if defined(HAVE_WIN32_THREADS) CRITICAL_SECTION crit_; // WIN32 critical section. #endif JTCMutex internal_; // Internal mutex. int count_; // Number of times the mutex has been aquired. JTCThreadId owner_; // Current owner of the mutex. friend class JTCCondHelper; friend class JTCCond; public: JTCRecursiveMutex(); ~JTCRecursiveMutex(); // // Lock the mutex. // void lock() const; // // Unlock the mutex. // void unlock() const; // // Get the thread id of the owning thread. // JTCThreadId _JTC_getId() const; }; #endif