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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #include "VMS/Mutex_POSIX.h"
00074 #include "VMS/Timestamp.h"
00075 #include <unistd.h>
00076 #include <sys/time.h>
00077
00078
00079 #if defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS - 200112L) >= 0L
00080 #if defined(_POSIX_THREADS) && (_POSIX_THREADS - 200112L) >= 0L
00081 #define POCO_HAVE_MUTEX_TIMEOUT
00082 #endif
00083 #endif
00084
00085
00086 namespace Poco {
00087
00088
00089 MutexImpl::MutexImpl()
00090 {
00091 pthread_mutexattr_t attr;
00092 pthread_mutexattr_init(&attr);
00093 #if defined(PTHREAD_MUTEX_RECURSIVE_NP)
00094 pthread_mutexattr_settype_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
00095 #else
00096 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
00097 #endif
00098 if (pthread_mutex_init(&_mutex, &attr))
00099 {
00100 pthread_mutexattr_destroy(&attr);
00101 throw SystemException("cannot create mutex");
00102 }
00103 pthread_mutexattr_destroy(&attr);
00104 }
00105
00106
00107 MutexImpl::MutexImpl(bool fast)
00108 {
00109 pthread_mutexattr_t attr;
00110 pthread_mutexattr_init(&attr);
00111 #if defined(PTHREAD_MUTEX_RECURSIVE_NP)
00112 pthread_mutexattr_settype_np(&attr, fast ? PTHREAD_MUTEX_NORMAL_NP : PTHREAD_MUTEX_RECURSIVE_NP);
00113 #else
00114 pthread_mutexattr_settype(&attr, fast ? PTHREAD_MUTEX_NORMAL : PTHREAD_MUTEX_RECURSIVE);
00115 #endif
00116 if (pthread_mutex_init(&_mutex, &attr))
00117 {
00118 pthread_mutexattr_destroy(&attr);
00119 throw SystemException("cannot create mutex");
00120 }
00121 pthread_mutexattr_destroy(&attr);
00122 }
00123
00124
00125 MutexImpl::~MutexImpl()
00126 {
00127 pthread_mutex_destroy(&_mutex);
00128 }
00129
00130
00131 bool MutexImpl::tryLockImpl(long milliseconds)
00132 {
00133 #if defined(POCO_HAVE_MUTEX_TIMEOUT)
00134 struct timespec abstime;
00135 struct timeval tv;
00136 gettimeofday(&tv, NULL);
00137 abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
00138 abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000;
00139 if (abstime.tv_nsec >= 1000000000)
00140 {
00141 abstime.tv_nsec -= 1000000000;
00142 abstime.tv_sec++;
00143 }
00144 int rc = pthread_mutex_timedlock(&_mutex, &abstime);
00145 if (rc == 0)
00146 return true;
00147 else if (rc == ETIMEDOUT)
00148 return false;
00149 else
00150 throw SystemException("cannot lock mutex");
00151 #else
00152 const int sleepMillis = 5;
00153 Timestamp now;
00154 Timestamp::TimeDiff diff(Timestamp::TimeDiff(milliseconds)*1000);
00155 do
00156 {
00157 int rc = pthread_mutex_trylock(&_mutex);
00158 if (rc == 0)
00159 return true;
00160 else if (rc != EBUSY)
00161 throw SystemException("cannot lock mutex");
00162 struct timeval tv;
00163 tv.tv_sec = 0;
00164 tv.tv_usec = sleepMillis * 1000;
00165 select(0, NULL, NULL, NULL, &tv);
00166 }
00167 while (!now.isElapsed(diff));
00168 return false;
00169 #endif
00170 }
00171
00172
00173 FastMutexImpl::FastMutexImpl(): MutexImpl(true)
00174 {
00175 }
00176
00177
00178 FastMutexImpl::~FastMutexImpl()
00179 {
00180 }
00181
00182
00183 }