blob: a2e427600ae8bf4a69c1b54f0d475e3b98102853 [file] [log] [blame]
Marc Slemko66949872006-07-15 01:52:39 +00001#include "Monitor.h"
Marc Slemko0e53ccd2006-07-17 23:51:05 +00002#include "Util.h"
Marc Slemko66949872006-07-15 01:52:39 +00003
4#include <assert.h>
5#include <errno.h>
6#include <pthread.h>
7
Marc Slemko0e53ccd2006-07-17 23:51:05 +00008
Marc Slemko66949872006-07-15 01:52:39 +00009namespace facebook { namespace thrift { namespace concurrency {
10
11/** Monitor implementation using the POSIX pthread library
12
13 @author marc
Marc Slemko0e53ccd2006-07-17 23:51:05 +000014 @version $Id:$ */
Marc Slemko66949872006-07-15 01:52:39 +000015
16class Monitor::Impl {
17
18 public:
19
20 Impl() :
21 mutexInitialized(false) {
22
23 /* XXX
24 Need to fix this to handle failures without leaking. */
25
26 assert(pthread_mutex_init(&_pthread_mutex, NULL) == 0);
27
28 mutexInitialized = true;
29
30 assert(pthread_cond_init(&_pthread_cond, NULL) == 0);
31 }
32
33 ~Impl() {
34
35 if(mutexInitialized) {
36
37 mutexInitialized = false;
38
39 assert(pthread_mutex_destroy(&_pthread_mutex) == 0);
40 }
41
42 if(condInitialized) {
43
44 condInitialized = false;
45
46 assert(pthread_cond_destroy(&_pthread_cond) == 0);
47 }
48 }
49
50 void lock() const {pthread_mutex_lock(&_pthread_mutex);}
51
52 void unlock() const {pthread_mutex_unlock(&_pthread_mutex);}
53
54 void wait(long long timeout) const {
55
56 // XXX Need to assert that caller owns mutex
57
58 if(timeout == 0LL) {
59
60 pthread_cond_wait(&_pthread_cond, &_pthread_mutex);
61
62 } else {
63
64 struct timespec abstime;
65
Marc Slemko0e53ccd2006-07-17 23:51:05 +000066 Util::toAbsoluteTimespec(abstime, timeout);
Marc Slemko66949872006-07-15 01:52:39 +000067
68 int result = pthread_cond_timedwait(&_pthread_cond, &_pthread_mutex, &abstime);
69
70 if(result == ETIMEDOUT) {
71
72 // XXX If result is timeout need to throw timeout exception
73 }
74 }
75 }
76
77 void notify() {
78
79 // XXX Need to assert that caller owns mutex
80
81 assert(pthread_cond_signal(&_pthread_cond) == 0);
82 }
83
84 void notifyAll() {
85
86 // XXX Need to assert that caller owns mutex
87
88 assert(pthread_cond_broadcast(&_pthread_cond) == 0);
89 }
90
91private:
92
Marc Slemko66949872006-07-15 01:52:39 +000093 mutable pthread_mutex_t _pthread_mutex;
94
95 mutable bool mutexInitialized;
96
97 mutable pthread_cond_t _pthread_cond;
98
99 mutable bool condInitialized;
100};
101
102Monitor::Monitor() : _impl(new Monitor::Impl()) {}
103
104 Monitor::~Monitor() { delete _impl;}
105
106void Monitor::lock() const {_impl->lock();}
107
108void Monitor::unlock() const {_impl->unlock();}
109
110void Monitor::wait(long long timeout) const {_impl->wait(timeout);}
111
112void Monitor::notify() const {_impl->notify();}
113
114void Monitor::notifyAll() const {_impl->notifyAll();}
115
116}}} // facebook::thrift::concurrency
117