10
10
#include " lock_and_signal.h"
11
11
12
12
#if defined(__WIN32__)
13
- lock_and_signal::lock_and_signal () {
13
+ lock_and_signal::lock_and_signal ()
14
+ : alive(true )
15
+ {
14
16
// FIXME: In order to match the behavior of pthread_cond_broadcast on
15
17
// Windows, we create manual reset events. This however breaks the
16
18
// behavior of pthread_cond_signal, fixing this is quite involved:
@@ -22,7 +24,7 @@ lock_and_signal::lock_and_signal() {
22
24
23
25
#else
24
26
lock_and_signal::lock_and_signal ()
25
- : _locked(false )
27
+ : _locked(false ), alive( true )
26
28
{
27
29
CHECKED (pthread_cond_init (&_cond, NULL ));
28
30
CHECKED (pthread_mutex_init (&_mutex, NULL ));
@@ -36,6 +38,7 @@ lock_and_signal::~lock_and_signal() {
36
38
CHECKED (pthread_cond_destroy (&_cond));
37
39
CHECKED (pthread_mutex_destroy (&_mutex));
38
40
#endif
41
+ alive = false ;
39
42
}
40
43
41
44
void lock_and_signal::lock () {
@@ -65,11 +68,14 @@ void lock_and_signal::wait() {
65
68
timed_wait (0 );
66
69
}
67
70
68
- void lock_and_signal::timed_wait (size_t timeout_in_ns) {
71
+ bool lock_and_signal::timed_wait (size_t timeout_in_ns) {
72
+ _locked = false ;
73
+ bool rv = true ;
69
74
#if defined(__WIN32__)
70
75
LeaveCriticalSection (&_cs);
71
76
WaitForSingleObject (_event, INFINITE);
72
77
EnterCriticalSection (&_cs);
78
+ _holding_thread = GetCurrentThreadId ();
73
79
#else
74
80
if (timeout_in_ns == 0 ) {
75
81
CHECKED (pthread_cond_wait (&_cond, &_mutex));
@@ -79,9 +85,29 @@ void lock_and_signal::timed_wait(size_t timeout_in_ns) {
79
85
timespec time_spec;
80
86
time_spec.tv_sec = time_val.tv_sec + 0 ;
81
87
time_spec.tv_nsec = time_val.tv_usec * 1000 + timeout_in_ns;
82
- CHECKED (pthread_cond_timedwait (&_cond, &_mutex, &time_spec));
88
+ if (time_spec.tv_nsec >= 1000000000 ) {
89
+ time_spec.tv_sec ++;
90
+ time_spec.tv_nsec -= 1000000000 ;
91
+ }
92
+ int cond_wait_status
93
+ = pthread_cond_timedwait (&_cond, &_mutex, &time_spec);
94
+ switch (cond_wait_status) {
95
+ case 0 :
96
+ // successfully grabbed the lock.
97
+ break ;
98
+ case ETIMEDOUT:
99
+ // Oops, we timed out.
100
+ rv = false ;
101
+ break ;
102
+ default :
103
+ // Error
104
+ CHECKED (cond_wait_status);
105
+ }
83
106
}
107
+ _holding_thread = pthread_self ();
84
108
#endif
109
+ _locked = true ;
110
+ return rv;
85
111
}
86
112
87
113
/* *
0 commit comments