blob: f6144ba710657d24885baa9b8e5e0c34621b2ed1 [file] [log] [blame]
Marc Slemko66949872006-07-15 01:52:39 +00001#include "Monitor.h"
Marc Slemko8a40a762006-07-19 17:46:50 +00002#include "Exception.h"
Marc Slemko0e53ccd2006-07-17 23:51:05 +00003#include "Util.h"
Marc Slemko66949872006-07-15 01:52:39 +00004
5#include <assert.h>
6#include <errno.h>
Marc Slemko8a40a762006-07-19 17:46:50 +00007
8#include <iostream>
9
Marc Slemko66949872006-07-15 01:52:39 +000010#include <pthread.h>
11
Marc Slemko0e53ccd2006-07-17 23:51:05 +000012
Marc Slemko66949872006-07-15 01:52:39 +000013namespace facebook { namespace thrift { namespace concurrency {
14
15/** Monitor implementation using the POSIX pthread library
16
17 @author marc
Marc Slemko0e53ccd2006-07-17 23:51:05 +000018 @version $Id:$ */
Marc Slemko66949872006-07-15 01:52:39 +000019
20class Monitor::Impl {
21
22 public:
23
24 Impl() :
25 mutexInitialized(false) {
26
27 /* XXX
28 Need to fix this to handle failures without leaking. */
29
30 assert(pthread_mutex_init(&_pthread_mutex, NULL) == 0);
31
32 mutexInitialized = true;
33
34 assert(pthread_cond_init(&_pthread_cond, NULL) == 0);
35 }
36
37 ~Impl() {
38
39 if(mutexInitialized) {
40
41 mutexInitialized = false;
42
43 assert(pthread_mutex_destroy(&_pthread_mutex) == 0);
44 }
45
46 if(condInitialized) {
47
48 condInitialized = false;
49
50 assert(pthread_cond_destroy(&_pthread_cond) == 0);
51 }
52 }
53
54 void lock() const {pthread_mutex_lock(&_pthread_mutex);}
55
56 void unlock() const {pthread_mutex_unlock(&_pthread_mutex);}
57
58 void wait(long long timeout) const {
59
60 // XXX Need to assert that caller owns mutex
61
62 if(timeout == 0LL) {
63
Marc Slemko8a40a762006-07-19 17:46:50 +000064 assert(pthread_cond_wait(&_pthread_cond, &_pthread_mutex) == 0);
Marc Slemko66949872006-07-15 01:52:39 +000065
66 } else {
67
68 struct timespec abstime;
69
Marc Slemko66949872006-07-15 01:52:39 +000070 int result = pthread_cond_timedwait(&_pthread_cond, &_pthread_mutex, &abstime);
71
72 if(result == ETIMEDOUT) {
73
Marc Slemko8a40a762006-07-19 17:46:50 +000074 // XXX Add assert once currentTime is fixed to have ms resolution or better
75
76 // assert(Util::currentTime() >= (now + timeout));
Marc Slemko66949872006-07-15 01:52:39 +000077 }
78 }
79 }
80
81 void notify() {
82
83 // XXX Need to assert that caller owns mutex
84
85 assert(pthread_cond_signal(&_pthread_cond) == 0);
86 }
87
88 void notifyAll() {
89
90 // XXX Need to assert that caller owns mutex
91
92 assert(pthread_cond_broadcast(&_pthread_cond) == 0);
93 }
94
95private:
96
Marc Slemko66949872006-07-15 01:52:39 +000097 mutable pthread_mutex_t _pthread_mutex;
98
99 mutable bool mutexInitialized;
100
101 mutable pthread_cond_t _pthread_cond;
102
103 mutable bool condInitialized;
104};
105
106Monitor::Monitor() : _impl(new Monitor::Impl()) {}
107
Marc Slemko8a40a762006-07-19 17:46:50 +0000108Monitor::~Monitor() { delete _impl;}
Marc Slemko66949872006-07-15 01:52:39 +0000109
110void Monitor::lock() const {_impl->lock();}
111
112void Monitor::unlock() const {_impl->unlock();}
113
114void Monitor::wait(long long timeout) const {_impl->wait(timeout);}
115
116void Monitor::notify() const {_impl->notify();}
117
118void Monitor::notifyAll() const {_impl->notifyAll();}
119
120}}} // facebook::thrift::concurrency
121