Skip to content

Commit f76e6c3

Browse files
committed
rt: Fix lock_held_by_current_thread
This simplifies the check for thread ownership by removing the _locked flag and just comparing against the thread ID of the last thread to take the lock. If the running thread took the lock _holding_thread will be equal to pthread_self(); if _holding_thread is some other value then the running thread does not have the lock. Setting a pthread_t to 0 like this is not portable but should work on every platform we are likely to care about for the near future.
1 parent 6b5f786 commit f76e6c3

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

src/rt/sync/lock_and_signal.cpp

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <assert.h>
12
#include "../globals.h"
23

34
/*
@@ -9,8 +10,13 @@
910

1011
#include "lock_and_signal.h"
1112

13+
// FIXME: This is not a portable way of specifying an invalid pthread_t
14+
#define INVALID_THREAD 0
15+
16+
1217
#if defined(__WIN32__)
1318
lock_and_signal::lock_and_signal()
19+
: _holding_thread(INVALID_THREAD)
1420
{
1521
// FIXME: In order to match the behavior of pthread_cond_broadcast on
1622
// Windows, we create manual reset events. This however breaks the
@@ -23,7 +29,7 @@ lock_and_signal::lock_and_signal()
2329

2430
#else
2531
lock_and_signal::lock_and_signal()
26-
: _locked(false)
32+
: _holding_thread(INVALID_THREAD)
2733
{
2834
CHECKED(pthread_cond_init(&_cond, NULL));
2935
CHECKED(pthread_mutex_init(&_mutex, NULL));
@@ -47,11 +53,10 @@ void lock_and_signal::lock() {
4753
CHECKED(pthread_mutex_lock(&_mutex));
4854
_holding_thread = pthread_self();
4955
#endif
50-
_locked = true;
5156
}
5257

5358
void lock_and_signal::unlock() {
54-
_locked = false;
59+
_holding_thread = INVALID_THREAD;
5560
#if defined(__WIN32__)
5661
LeaveCriticalSection(&_cs);
5762
#else
@@ -67,7 +72,8 @@ void lock_and_signal::wait() {
6772
}
6873

6974
bool lock_and_signal::timed_wait(size_t timeout_in_ms) {
70-
_locked = false;
75+
assert(lock_held_by_current_thread());
76+
_holding_thread = INVALID_THREAD;
7177
bool rv = true;
7278
#if defined(__WIN32__)
7379
LeaveCriticalSection(&_cs);
@@ -105,7 +111,6 @@ bool lock_and_signal::timed_wait(size_t timeout_in_ms) {
105111
}
106112
_holding_thread = pthread_self();
107113
#endif
108-
_locked = true;
109114
return rv;
110115
}
111116

@@ -134,9 +139,9 @@ void lock_and_signal::signal_all() {
134139
bool lock_and_signal::lock_held_by_current_thread()
135140
{
136141
#if defined(__WIN32__)
137-
return _locked && _holding_thread == GetCurrentThreadId();
142+
return _holding_thread == GetCurrentThreadId();
138143
#else
139-
return _locked && _holding_thread == pthread_self();
144+
return pthread_equal(_holding_thread, pthread_self());
140145
#endif
141146
}
142147

src/rt/sync/lock_and_signal.h

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ class lock_and_signal {
1313

1414
pthread_t _holding_thread;
1515
#endif
16-
bool _locked;
1716

1817
public:
1918
lock_and_signal();

0 commit comments

Comments
 (0)