]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | #include "condition_variable_debug.h" |
2 | #include "common/mutex_debug.h" | |
3 | ||
4 | namespace ceph { | |
5 | ||
6 | condition_variable_debug::condition_variable_debug() | |
7 | : waiter_mutex{nullptr} | |
8 | { | |
9 | int r = pthread_cond_init(&cond, nullptr); | |
10 | if (r) { | |
11 | throw std::system_error(r, std::generic_category()); | |
12 | } | |
13 | } | |
14 | ||
15 | condition_variable_debug::~condition_variable_debug() | |
16 | { | |
17 | pthread_cond_destroy(&cond); | |
18 | } | |
19 | ||
20 | void condition_variable_debug::wait(std::unique_lock<mutex_debug>& lock) | |
21 | { | |
22 | // make sure this cond is used with one mutex only | |
23 | ceph_assert(waiter_mutex == nullptr || | |
24 | waiter_mutex == lock.mutex()); | |
25 | waiter_mutex = lock.mutex(); | |
26 | ceph_assert(waiter_mutex->is_locked()); | |
27 | waiter_mutex->_pre_unlock(); | |
28 | if (int r = pthread_cond_wait(&cond, waiter_mutex->native_handle()); | |
29 | r != 0) { | |
30 | throw std::system_error(r, std::generic_category()); | |
31 | } | |
32 | waiter_mutex->_post_lock(); | |
33 | } | |
34 | ||
35 | void condition_variable_debug::notify_one() | |
36 | { | |
37 | // make sure signaler is holding the waiter's lock. | |
38 | ceph_assert(waiter_mutex == nullptr || | |
39 | waiter_mutex->is_locked()); | |
40 | if (int r = pthread_cond_signal(&cond); r != 0) { | |
41 | throw std::system_error(r, std::generic_category()); | |
42 | } | |
43 | } | |
44 | ||
45 | void condition_variable_debug::notify_all(bool sloppy) | |
46 | { | |
9f95a23c TL |
47 | if (!sloppy) { |
48 | // make sure signaler is holding the waiter's lock. | |
49 | ceph_assert(waiter_mutex == NULL || | |
50 | waiter_mutex->is_locked()); | |
51 | } | |
11fdf7f2 TL |
52 | if (int r = pthread_cond_broadcast(&cond); r != 0 && !sloppy) { |
53 | throw std::system_error(r, std::generic_category()); | |
54 | } | |
55 | } | |
56 | ||
57 | std::cv_status condition_variable_debug::_wait_until(mutex_debug* mutex, | |
58 | timespec* ts) | |
59 | { | |
60 | // make sure this cond is used with one mutex only | |
61 | ceph_assert(waiter_mutex == nullptr || | |
62 | waiter_mutex == mutex); | |
63 | waiter_mutex = mutex; | |
64 | ceph_assert(waiter_mutex->is_locked()); | |
65 | ||
66 | waiter_mutex->_pre_unlock(); | |
67 | int r = pthread_cond_timedwait(&cond, waiter_mutex->native_handle(), ts); | |
68 | waiter_mutex->_post_lock(); | |
69 | switch (r) { | |
70 | case 0: | |
71 | return std::cv_status::no_timeout; | |
72 | case ETIMEDOUT: | |
73 | return std::cv_status::timeout; | |
74 | default: | |
75 | throw std::system_error(r, std::generic_category()); | |
76 | } | |
77 | } | |
78 | ||
79 | } // namespace ceph |