]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/condition_variable_debug.cc
import ceph quincy 17.2.6
[ceph.git] / ceph / src / common / condition_variable_debug.cc
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 {
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 }
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