| [1016] | 1 | // **********************************************************************
 | 
|---|
 | 2 | //
 | 
|---|
 | 3 | // Copyright (c) 2000
 | 
|---|
 | 4 | // Object Oriented Concepts, Inc.
 | 
|---|
 | 5 | // Billerica, MA, USA
 | 
|---|
 | 6 | //
 | 
|---|
 | 7 | // All Rights Reserved
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | // **********************************************************************
 | 
|---|
 | 10 | 
 | 
|---|
 | 11 | #ifndef JTC_MUTEX_H
 | 
|---|
 | 12 | #define JTC_MUTEX_H
 | 
|---|
 | 13 | 
 | 
|---|
 | 14 | //
 | 
|---|
 | 15 | // This class can be used to establish a critical section. Call the
 | 
|---|
 | 16 | // lock method to lock the mutex, and the unlock Method to unlock the
 | 
|---|
 | 17 | // mutex. If the mutex is currently locked the thread will be
 | 
|---|
 | 18 | // suspended until the mutex becomes unlocked.
 | 
|---|
 | 19 | //
 | 
|---|
 | 20 | class JTCMutex
 | 
|---|
 | 21 | {
 | 
|---|
 | 22 |     //
 | 
|---|
 | 23 |     // Hide copy constructor and assignment operator.
 | 
|---|
 | 24 |     //
 | 
|---|
 | 25 |     JTCMutex(const JTCMutex&);
 | 
|---|
 | 26 |     void operator=(const JTCMutex&);
 | 
|---|
 | 27 | 
 | 
|---|
 | 28 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 29 |     pthread_mutex_t lock_; // Pthread mutex.
 | 
|---|
 | 30 | #endif
 | 
|---|
 | 31 | 
 | 
|---|
 | 32 | #if defined(HAVE_WIN32_THREADS)
 | 
|---|
 | 33 |     CRITICAL_SECTION crit_; // WIN32 critical section.
 | 
|---|
 | 34 | #endif
 | 
|---|
 | 35 | 
 | 
|---|
 | 36 |     friend class JTCEvent;
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 | public:
 | 
|---|
 | 39 | 
 | 
|---|
 | 40 |     JTCMutex()
 | 
|---|
 | 41 |     {
 | 
|---|
 | 42 | #if defined(HAVE_POSIX_THREADS)
 | 
|---|
 | 43 |         JTC_SYSCALL_2(pthread_mutex_init, &lock_, 0, != 0)
 | 
|---|
 | 44 | #endif
 | 
|---|
 | 45 | #if defined(HAVE_DCE_THREADS)
 | 
|---|
 | 46 |         JTC_SYSCALL_2(pthread_mutex_init, &lock_, pthread_mutexattr_default,
 | 
|---|
 | 47 |                       != 0)
 | 
|---|
 | 48 | #endif
 | 
|---|
 | 49 | #if defined(HAVE_WIN32_THREADS)
 | 
|---|
 | 50 |         InitializeCriticalSection(&crit_);
 | 
|---|
 | 51 | #endif
 | 
|---|
 | 52 |     }
 | 
|---|
 | 53 |     ~JTCMutex()
 | 
|---|
 | 54 |     {
 | 
|---|
 | 55 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 56 |         pthread_mutex_destroy(&lock_);
 | 
|---|
 | 57 | #endif
 | 
|---|
 | 58 | #if defined(HAVE_WIN32_THREADS)
 | 
|---|
 | 59 |         DeleteCriticalSection(&crit_);
 | 
|---|
 | 60 | #endif
 | 
|---|
 | 61 |     }
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 |     //
 | 
|---|
 | 64 |     // Lock the mutex.
 | 
|---|
 | 65 |     //
 | 
|---|
 | 66 |     void lock() const
 | 
|---|
 | 67 |     {
 | 
|---|
 | 68 | #if defined(HAVE_WIN32_THREADS)
 | 
|---|
 | 69 | #endif
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 72 | #if defined(__GNUC__) && defined(__OPTIMIZE__)
 | 
|---|
 | 73 |         //
 | 
|---|
 | 74 |         // The optimizer for GCC 2.95.1 is broken. The following
 | 
|---|
 | 75 |         // three lines of code "fix" the problem.
 | 
|---|
 | 76 |         //
 | 
|---|
 | 77 |         volatile int i = 1;
 | 
|---|
 | 78 |         if (i == 0) 
 | 
|---|
 | 79 |             ++i;
 | 
|---|
 | 80 | #endif
 | 
|---|
 | 81 |         pthread_mutex_t* lock = &((JTCMutex*)this) -> lock_;
 | 
|---|
 | 82 |         JTC_SYSCALL_1(pthread_mutex_lock, lock, != 0)
 | 
|---|
 | 83 | #endif
 | 
|---|
 | 84 | #if defined(HAVE_WIN32_THREADS)
 | 
|---|
 | 85 |         CRITICAL_SECTION* crit = &((JTCMutex*)this) -> crit_;
 | 
|---|
 | 86 |         EnterCriticalSection(crit);
 | 
|---|
 | 87 | #endif
 | 
|---|
 | 88 |     }
 | 
|---|
 | 89 | 
 | 
|---|
 | 90 | 
 | 
|---|
 | 91 |     //
 | 
|---|
 | 92 |     // Unlock the mutex.
 | 
|---|
 | 93 |     //
 | 
|---|
 | 94 |     void unlock() const
 | 
|---|
 | 95 |     {
 | 
|---|
 | 96 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 97 |         pthread_mutex_t* lock = &((JTCMutex*)this) -> lock_;
 | 
|---|
 | 98 |         JTC_SYSCALL_1(pthread_mutex_unlock, lock, != 0)
 | 
|---|
 | 99 | #endif
 | 
|---|
 | 100 | #if defined(HAVE_WIN32_THREADS)
 | 
|---|
 | 101 |         CRITICAL_SECTION* crit = &((JTCMutex*)this) -> crit_;
 | 
|---|
 | 102 |         LeaveCriticalSection(crit);
 | 
|---|
 | 103 | #endif
 | 
|---|
 | 104 | 
 | 
|---|
 | 105 |     }
 | 
|---|
 | 106 | };
 | 
|---|
 | 107 | 
 | 
|---|
 | 108 | //
 | 
|---|
 | 109 | // Unlike the JTCMutex class this mutex can be locked recursively.
 | 
|---|
 | 110 | // That is it can be locked by a thread that already has the mutex
 | 
|---|
 | 111 | // locked.
 | 
|---|
 | 112 | //
 | 
|---|
 | 113 | class JTCRecursiveMutex
 | 
|---|
 | 114 | {
 | 
|---|
 | 115 |     //
 | 
|---|
 | 116 |     // Hide copy constructor and assignment operator.
 | 
|---|
 | 117 |     //
 | 
|---|
 | 118 |     JTCRecursiveMutex(const JTCRecursiveMutex&);
 | 
|---|
 | 119 |     void operator=(const JTCRecursiveMutex&);
 | 
|---|
 | 120 | 
 | 
|---|
 | 121 |     //
 | 
|---|
 | 122 |     // Internal non-const operations since mutable isn't supported
 | 
|---|
 | 123 |     // on some compilers.
 | 
|---|
 | 124 |     //
 | 
|---|
 | 125 |     void lockI(int count);
 | 
|---|
 | 126 |     void unlockI();
 | 
|---|
 | 127 | 
 | 
|---|
 | 128 |     //
 | 
|---|
 | 129 |     // Lock the mutex count times.
 | 
|---|
 | 130 |     //
 | 
|---|
 | 131 |     void lock(int count) const;
 | 
|---|
 | 132 | 
 | 
|---|
 | 133 | #if defined(HAVE_POSIX_THREADS) || defined(HAVE_DCE_THREADS)
 | 
|---|
 | 134 |     pthread_mutex_t crit_; // Pthreads mutex.
 | 
|---|
 | 135 | #endif
 | 
|---|
 | 136 | #if defined(HAVE_WIN32_THREADS)
 | 
|---|
 | 137 |     CRITICAL_SECTION crit_; // WIN32 critical section.
 | 
|---|
 | 138 | #endif
 | 
|---|
 | 139 |     JTCMutex internal_; // Internal mutex.
 | 
|---|
 | 140 |  
 | 
|---|
 | 141 |     int count_; // Number of times the mutex has been aquired.
 | 
|---|
 | 142 |     JTCThreadId owner_; // Current owner of the mutex.
 | 
|---|
 | 143 | 
 | 
|---|
 | 144 |     friend class JTCCondHelper;
 | 
|---|
 | 145 |     friend class JTCCond;
 | 
|---|
 | 146 | 
 | 
|---|
 | 147 | public:
 | 
|---|
 | 148 | 
 | 
|---|
 | 149 |     JTCRecursiveMutex();
 | 
|---|
 | 150 |     ~JTCRecursiveMutex();
 | 
|---|
 | 151 | 
 | 
|---|
 | 152 |     //
 | 
|---|
 | 153 |     // Lock the mutex.
 | 
|---|
 | 154 |     //
 | 
|---|
 | 155 |     void lock() const;
 | 
|---|
 | 156 |     
 | 
|---|
 | 157 |     //
 | 
|---|
 | 158 |     // Unlock the mutex.
 | 
|---|
 | 159 |     //
 | 
|---|
 | 160 |     void unlock() const;
 | 
|---|
 | 161 | 
 | 
|---|
 | 162 |     //
 | 
|---|
 | 163 |     // Get the thread id of the owning thread.
 | 
|---|
 | 164 |     //
 | 
|---|
 | 165 |     JTCThreadId _JTC_getId() const;
 | 
|---|
 | 166 | };
 | 
|---|
 | 167 | 
 | 
|---|
 | 168 | #endif
 | 
|---|