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
00031
00032
00038 #include "blocxx/BLOCXX_config.h"
00039 #include "blocxx/MutexImpl.hpp"
00040 #include <cerrno>
00041 #include <cassert>
00042
00043 namespace BLOCXX_NAMESPACE
00044 {
00045
00046 namespace MutexImpl
00047 {
00048
00054 int
00055 createMutex(Mutex_t& handle)
00056 {
00057 #if defined (BLOCXX_USE_PTHREAD)
00058 pthread_mutexattr_t attr;
00059 int res = pthread_mutexattr_init(&attr);
00060 assert(res == 0);
00061 if (res != 0)
00062 {
00063 return -1;
00064 }
00065
00066 #if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00067 res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
00068 assert(res == 0);
00069 if (res != 0)
00070 {
00071 pthread_mutexattr_destroy(&attr);
00072 return -1;
00073 }
00074 #endif
00075
00076 res = pthread_mutex_init(&handle.mutex, &attr);
00077 pthread_mutexattr_destroy(&attr);
00078 if (res != 0)
00079 {
00080 return -1;
00081 }
00082
00083 #if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00084 res = pthread_cond_init(&handle.unlocked, 0);
00085 if (res != 0)
00086 {
00087 pthread_mutex_destroy(&handle.mutex);
00088 return -1;
00089 }
00090
00091 handle.valid_id = false;
00092 handle.count = 0;
00093 #endif
00094 return 0;
00095 #elif defined (BLOCXX_WIN32)
00096 handle = new CRITICAL_SECTION;
00097 assert(handle);
00098 InitializeCriticalSection(handle);
00099 return 0;
00100 #else
00101 #error "port me!"
00102 #endif
00103 }
00113 int
00114 destroyMutex(Mutex_t& handle)
00115 {
00116 #if defined (BLOCXX_USE_PTHREAD)
00117 switch (pthread_mutex_destroy(&handle.mutex))
00118 {
00119 case 0:
00120 break;
00121 case EBUSY:
00122 return -1;
00123 break;
00124 default:
00125 return -2;
00126 }
00127 int res = 0;
00128 #if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00129 res = pthread_cond_destroy(&handle.unlocked);
00130 assert(res == 0);
00131 #endif
00132 return res;
00133 #elif defined(BLOCXX_WIN32)
00134 if(handle)
00135 {
00136 DeleteCriticalSection(handle);
00137 delete handle;
00138 handle = 0;
00139 }
00140 return 0;
00141 #else
00142 #error "port me!"
00143 #endif
00144 }
00153 int
00154 acquireMutex(Mutex_t& handle)
00155 {
00156 #if defined (BLOCXX_USE_PTHREAD)
00157 int res = pthread_mutex_lock(&handle.mutex);
00158 assert(res == 0);
00159
00160 #if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00161 pthread_t tid = pthread_self();
00162 if (handle.valid_id && pthread_equal(handle.thread_id, tid))
00163 {
00164 ++handle.count;
00165 }
00166 else
00167 {
00168 while (handle.valid_id)
00169 {
00170 res = pthread_cond_wait(&handle.unlocked, &handle.mutex);
00171 assert(res == 0);
00172 }
00173
00174 handle.thread_id = tid;
00175 handle.valid_id = true;
00176 handle.count = 1;
00177 }
00178
00179 res = pthread_mutex_unlock(&handle.mutex);
00180 assert(res == 0);
00181 #endif
00182 return res;
00183 #elif defined(BLOCXX_WIN32)
00184 EnterCriticalSection(handle);
00185 return 0;
00186 #else
00187 #error "port me!"
00188 #endif
00189 }
00196 int
00197 releaseMutex(Mutex_t& handle)
00198 {
00199 #if defined (BLOCXX_USE_PTHREAD)
00200 #if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00201 int res = pthread_mutex_unlock(&handle.mutex);
00202 assert(res == 0);
00203 return res;
00204 #else
00205 int res = 0;
00206 res = pthread_mutex_lock(&handle.mutex);
00207 assert(res == 0);
00208
00209 pthread_t tid = pthread_self();
00210 if (handle.valid_id && !pthread_equal(handle.thread_id, tid))
00211 {
00212 res = pthread_mutex_unlock(&handle.mutex);
00213 assert(res == 0);
00214 return -1;
00215 }
00216
00217 if (--handle.count == 0)
00218 {
00219 assert(handle.valid_id);
00220 handle.valid_id = false;
00221
00222 res = pthread_cond_signal(&handle.unlocked);
00223 assert(res == 0);
00224 }
00225
00226 res = pthread_mutex_unlock(&handle.mutex);
00227 assert(res == 0);
00228 return res;
00229 #endif
00230 #elif defined (BLOCXX_WIN32)
00231 LeaveCriticalSection(handle);
00232 return 0;
00233 #else
00234 #error "port me!"
00235 #endif
00236 }
00237
00238 }
00239 }
00240