00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00029
00030 namespace log4cplus { namespace thread {
00031
00032
00033 #define LOG4CPLUS_THROW_RTE(msg) \
00034 do { detail::syncprims_throw_exception (msg, __FILE__, __LINE__); } while (0)
00035
00036
00037
00038
00039
00040 inline
00041 Mutex::Mutex ()
00042 {
00043 int ret = pthread_mutex_init (&mtx, 0);
00044 if (ret != 0)
00045 LOG4CPLUS_THROW_RTE ("Mutex::Mutex");
00046 }
00047
00048
00049 inline
00050 Mutex::~Mutex ()
00051 {
00052 int ret = pthread_mutex_destroy (&mtx);
00053 if (ret != 0)
00054 LOG4CPLUS_THROW_RTE ("Mutex::~Mutex");
00055 }
00056
00057
00058 inline
00059 void
00060 Mutex::lock () const
00061 {
00062 int ret = pthread_mutex_lock (&mtx);
00063 if (ret != 0)
00064 LOG4CPLUS_THROW_RTE ("Mutex::lock");
00065 }
00066
00067
00068 inline
00069 void
00070 Mutex::unlock () const
00071 {
00072 int ret = pthread_mutex_unlock (&mtx);
00073 if (ret != 0)
00074 LOG4CPLUS_THROW_RTE ("Mutex::unlock");
00075 }
00076
00077
00078
00079
00080
00081
00082 inline
00083 Semaphore::Semaphore (unsigned max, unsigned initial)
00084 {
00085 int ret = sem_init (&sem, max, initial);
00086 if (ret != 0)
00087 LOG4CPLUS_THROW_RTE ("Semaphore::Semaphore");
00088 }
00089
00090
00091 inline
00092 Semaphore::~Semaphore ()
00093 try
00094 {
00095 int ret = sem_destroy (&sem);
00096 if (ret != 0)
00097 LOG4CPLUS_THROW_RTE ("Semaphore::~Semaphore");
00098 }
00099 catch (...)
00100 { }
00101
00102
00103 inline
00104 void
00105 Semaphore::unlock () const
00106 {
00107 int ret = sem_post (&sem);
00108 if (ret != 0)
00109 LOG4CPLUS_THROW_RTE ("Semaphore::unlock");
00110 }
00111
00112
00113 inline
00114 void
00115 Semaphore::lock () const
00116 {
00117 int ret = sem_wait (&sem);
00118 if (ret != 0)
00119 LOG4CPLUS_THROW_RTE ("Semaphore::lock");
00120 }
00121
00122
00123
00124
00125
00126
00127 inline
00128 ManualResetEvent::ManualResetEvent (bool sig)
00129 : sigcount (0)
00130 , signaled (sig)
00131 {
00132 int ret = pthread_cond_init (&cv, 0);
00133 if (ret != 0)
00134 LOG4CPLUS_THROW_RTE ("ManualResetEvent::ManualResetEvent");
00135 }
00136
00137
00138 inline
00139 ManualResetEvent::~ManualResetEvent ()
00140 try
00141 {
00142 int ret = pthread_cond_destroy (&cv);
00143 if (ret != 0)
00144 LOG4CPLUS_THROW_RTE ("ManualResetEvent::~ManualResetEvent");
00145 }
00146 catch (...)
00147 { }
00148
00149
00150 inline
00151 void
00152 ManualResetEvent::signal () const
00153 {
00154 MutexGuard mguard (mtx);
00155
00156 signaled = true;
00157 sigcount += 1;
00158 int ret = pthread_cond_broadcast (&cv);
00159 if (ret != 0)
00160 LOG4CPLUS_THROW_RTE ("ManualResetEVent::signal");
00161
00162 }
00163
00164
00165 inline
00166 void
00167 ManualResetEvent::wait () const
00168 {
00169 MutexGuard mguard (mtx);
00170
00171 if (! signaled)
00172 {
00173 unsigned prev_count = sigcount;
00174 do
00175 {
00176 int ret = pthread_cond_wait (&cv, &mtx.mtx);
00177 if (ret != 0)
00178 {
00179 mguard.unlock ();
00180 mguard.detach ();
00181 LOG4CPLUS_THROW_RTE ("ManualResetEvent::wait");
00182 }
00183 }
00184 while (prev_count == sigcount);
00185 }
00186 }
00187
00188
00189 inline
00190 bool
00191 ManualResetEvent::timed_wait (unsigned long msec) const
00192 {
00193 MutexGuard mguard (mtx);
00194
00195 if (! signaled)
00196 {
00197 helpers::Time const wakeup_time (helpers::Time::gettimeofday ()
00198 + helpers::Time (msec / 1000, (msec % 1000) * 1000));
00199 struct timespec const ts = {wakeup_time.sec (),
00200 wakeup_time.usec () * 1000};
00201 unsigned prev_count = sigcount;
00202 do
00203 {
00204 int ret = pthread_cond_timedwait (&cv, &mtx.mtx, &ts);
00205 switch (ret)
00206 {
00207 case 0:
00208 break;
00209
00210 case ETIMEDOUT:
00211 return false;
00212
00213 default:
00214 mguard.unlock ();
00215 mguard.detach ();
00216 LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait");
00217 }
00218 }
00219 while (prev_count == sigcount);
00220 }
00221
00222 return true;
00223 }
00224
00225
00226 inline
00227 void
00228 ManualResetEvent::reset () const
00229 {
00230 MutexGuard mguard (mtx);
00231
00232 signaled = false;
00233 }
00234
00235
00236 #undef LOG4CPLUS_THROW_RTE
00237
00238
00239 } }