00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_MutexImpl.hpp"
00038 #include <cerrno>
00039 #include <cassert>
00040
00041 namespace OW_NAMESPACE
00042 {
00043
00044 namespace MutexImpl
00045 {
00046
00052 int
00053 createMutex(Mutex_t& handle)
00054 {
00055 #if defined (OW_USE_PTHREAD)
00056 pthread_mutexattr_t attr;
00057 int res = pthread_mutexattr_init(&attr);
00058 assert(res == 0);
00059 if (res != 0)
00060 {
00061 return -1;
00062 }
00063
00064 #if defined(OW_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00065 res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
00066 assert(res == 0);
00067 if (res != 0)
00068 {
00069 pthread_mutexattr_destroy(&attr);
00070 return -1;
00071 }
00072 #endif
00073
00074 res = pthread_mutex_init(&handle.mutex, &attr);
00075 pthread_mutexattr_destroy(&attr);
00076 if (res != 0)
00077 {
00078 return -1;
00079 }
00080
00081 #if !defined(OW_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00082 res = pthread_cond_init(&handle.unlocked, 0);
00083 if (res != 0)
00084 {
00085 pthread_mutex_destroy(&handle.mutex);
00086 return -1;
00087 }
00088
00089 handle.valid_id = false;
00090 handle.count = 0;
00091 #endif
00092 return 0;
00093 #elif defined (OW_WIN32)
00094 handle = new CRITICAL_SECTION;
00095 assert(handle);
00096 InitializeCriticalSection(handle);
00097 return 0;
00098 #else
00099 #error "port me!"
00100 #endif
00101 }
00111 int
00112 destroyMutex(Mutex_t& handle)
00113 {
00114 #if defined (OW_USE_PTHREAD)
00115 switch (pthread_mutex_destroy(&handle.mutex))
00116 {
00117 case 0:
00118 break;
00119 case EBUSY:
00120 return -1;
00121 break;
00122 default:
00123 return -2;
00124 }
00125 int res = 0;
00126 #if !defined(OW_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00127 res = pthread_cond_destroy(&handle.unlocked);
00128 assert(res == 0);
00129 #endif
00130 return res;
00131 #elif defined(OW_WIN32)
00132 if(handle)
00133 {
00134 DeleteCriticalSection(handle);
00135 delete handle;
00136 handle = 0;
00137 }
00138 return 0;
00139 #else
00140 #error "port me!"
00141 #endif
00142 }
00151 int
00152 acquireMutex(Mutex_t& handle)
00153 {
00154 #if defined (OW_USE_PTHREAD)
00155 int res = pthread_mutex_lock(&handle.mutex);
00156 assert(res == 0);
00157
00158 #if !defined(OW_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00159 pthread_t tid = pthread_self();
00160 if (handle.valid_id && pthread_equal(handle.thread_id, tid))
00161 {
00162 ++handle.count;
00163 }
00164 else
00165 {
00166 while (handle.valid_id)
00167 {
00168 res = pthread_cond_wait(&handle.unlocked, &handle.mutex);
00169 assert(res == 0);
00170 }
00171
00172 handle.thread_id = tid;
00173 handle.valid_id = true;
00174 handle.count = 1;
00175 }
00176
00177 res = pthread_mutex_unlock(&handle.mutex);
00178 assert(res == 0);
00179 #endif
00180 return res;
00181 #elif defined(OW_WIN32)
00182 EnterCriticalSection(handle);
00183 return 0;
00184 #else
00185 #error "port me!"
00186 #endif
00187 }
00194 int
00195 releaseMutex(Mutex_t& handle)
00196 {
00197 #if defined (OW_USE_PTHREAD)
00198 #if defined(OW_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00199 int res = pthread_mutex_unlock(&handle.mutex);
00200 assert(res == 0);
00201 return res;
00202 #else
00203 int res = 0;
00204 res = pthread_mutex_lock(&handle.mutex);
00205 assert(res == 0);
00206
00207 pthread_t tid = pthread_self();
00208 if (handle.valid_id && !pthread_equal(handle.thread_id, tid))
00209 {
00210 res = pthread_mutex_unlock(&handle.mutex);
00211 assert(res == 0);
00212 return -1;
00213 }
00214
00215 if (--handle.count == 0)
00216 {
00217 assert(handle.valid_id);
00218 handle.valid_id = false;
00219
00220 res = pthread_cond_signal(&handle.unlocked);
00221 assert(res == 0);
00222 }
00223
00224 res = pthread_mutex_unlock(&handle.mutex);
00225 assert(res == 0);
00226 return res;
00227 #endif
00228 #elif defined (OW_WIN32)
00229 LeaveCriticalSection(handle);
00230 return 0;
00231 #else
00232 #error "port me!"
00233 #endif
00234 }
00235
00236 }
00237 }
00238