Skip to content

Commit 91817a8

Browse files
committed
---
yaml --- r: 12246 b: refs/heads/master c: c8dc6fc h: refs/heads/master v: v3
1 parent 3555a23 commit 91817a8

File tree

7 files changed

+112
-1
lines changed

7 files changed

+112
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 609144f7a6adba552602feb7e50e7c4d6a815fae
2+
refs/heads/master: c8dc6fcb4cd29e5fb6c509149871b869b951295d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/etc/x86.supp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,34 @@
389389
fun:uv_loop_delete
390390
}
391391

392+
{
393+
lock_and_signal-probably-threadsafe-access-outside-of-lock
394+
Helgrind:Race
395+
fun:_ZN15lock_and_signal27lock_held_by_current_threadEv
396+
...
397+
}
398+
399+
{
400+
lock_and_signal-probably-threadsafe-access-outside-of-lock2
401+
Helgrind:Race
402+
fun:_ZN15lock_and_signal6unlockEv
403+
...
404+
}
405+
406+
{
407+
lock_and_signal-probably-threadsafe-access-outside-of-lock3
408+
Helgrind:Race
409+
fun:_ZN15lock_and_signal4lockEv
410+
...
411+
}
412+
413+
{
414+
lock_and_signal-probably-threadsafe-access-outside-of-lock4
415+
Helgrind:Race
416+
fun:_ZN15lock_and_signal4waitEv
417+
...
418+
}
419+
392420
{
393421
uv-async-send-does-racy-things
394422
Helgrind:Race

trunk/src/rt/rust_port_selector.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ void
6969
rust_port_selector::msg_sent_on(rust_port *port) {
7070
rust_task *task = port->task;
7171

72+
port->lock.must_not_have_lock();
73+
7274
// Prevent two ports from trying to wake up the task
7375
// simultaneously
7476
scoped_lock with(rendezvous_lock);

trunk/src/rt/rust_sched_loop.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ rust_sched_loop::number_of_live_tasks() {
108108
*/
109109
void
110110
rust_sched_loop::reap_dead_tasks() {
111+
lock.must_have_lock();
112+
111113
if (dead_task == NULL) {
112114
return;
113115
}

trunk/src/rt/rust_task.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ rust_task::must_fail_from_being_killed() {
212212

213213
bool
214214
rust_task::must_fail_from_being_killed_unlocked() {
215+
kill_lock.must_have_lock();
215216
return killed && !reentered_rust_stack;
216217
}
217218

trunk/src/rt/sync/lock_and_signal.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@
1010

1111
#include "lock_and_signal.h"
1212

13+
// FIXME: This is not a portable way of specifying an invalid pthread_t
14+
#define INVALID_THREAD 0
15+
16+
1317
#if defined(__WIN32__)
1418
lock_and_signal::lock_and_signal()
19+
#if defined(DEBUG_LOCKS)
20+
: _holding_thread(INVALID_THREAD)
21+
#endif
1522
{
1623
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
1724

@@ -30,6 +37,9 @@ lock_and_signal::lock_and_signal()
3037

3138
#else
3239
lock_and_signal::lock_and_signal()
40+
#if defined(DEBUG_LOCKS)
41+
: _holding_thread(INVALID_THREAD)
42+
#endif
3343
{
3444
CHECKED(pthread_cond_init(&_cond, NULL));
3545
CHECKED(pthread_mutex_init(&_mutex, NULL));
@@ -47,14 +57,25 @@ lock_and_signal::~lock_and_signal() {
4757
}
4858

4959
void lock_and_signal::lock() {
60+
must_not_have_lock();
5061
#if defined(__WIN32__)
5162
EnterCriticalSection(&_cs);
63+
#if defined(DEBUG_LOCKS)
64+
_holding_thread = GetCurrentThreadId();
65+
#endif
5266
#else
5367
CHECKED(pthread_mutex_lock(&_mutex));
68+
#if defined(DEBUG_LOCKS)
69+
_holding_thread = pthread_self();
70+
#endif
5471
#endif
5572
}
5673

5774
void lock_and_signal::unlock() {
75+
must_have_lock();
76+
#if defined(DEBUG_LOCKS)
77+
_holding_thread = INVALID_THREAD;
78+
#endif
5879
#if defined(__WIN32__)
5980
LeaveCriticalSection(&_cs);
6081
#else
@@ -66,12 +87,24 @@ void lock_and_signal::unlock() {
6687
* Wait indefinitely until condition is signaled.
6788
*/
6889
void lock_and_signal::wait() {
90+
must_have_lock();
91+
#if defined(DEBUG_LOCKS)
92+
_holding_thread = INVALID_THREAD;
93+
#endif
6994
#if defined(__WIN32__)
7095
LeaveCriticalSection(&_cs);
7196
WaitForSingleObject(_event, INFINITE);
7297
EnterCriticalSection(&_cs);
98+
must_not_be_locked();
99+
#if defined(DEBUG_LOCKS)
100+
_holding_thread = GetCurrentThreadId();
101+
#endif
73102
#else
74103
CHECKED(pthread_cond_wait(&_cond, &_mutex));
104+
must_not_be_locked();
105+
#if defined(DEBUG_LOCKS)
106+
_holding_thread = pthread_self();
107+
#endif
75108
#endif
76109
}
77110

@@ -86,6 +119,32 @@ void lock_and_signal::signal() {
86119
#endif
87120
}
88121

122+
#if defined(DEBUG_LOCKS)
123+
bool lock_and_signal::lock_held_by_current_thread()
124+
{
125+
#if defined(__WIN32__)
126+
return _holding_thread == GetCurrentThreadId();
127+
#else
128+
return pthread_equal(_holding_thread, pthread_self());
129+
#endif
130+
}
131+
#endif
132+
133+
#if defined(DEBUG_LOCKS)
134+
void lock_and_signal::must_have_lock() {
135+
assert(lock_held_by_current_thread() && "must have lock");
136+
}
137+
void lock_and_signal::must_not_have_lock() {
138+
assert(!lock_held_by_current_thread() && "must not have lock");
139+
}
140+
void lock_and_signal::must_not_be_locked() {
141+
}
142+
#else
143+
void lock_and_signal::must_have_lock() { }
144+
void lock_and_signal::must_not_have_lock() { }
145+
void lock_and_signal::must_not_be_locked() { }
146+
#endif
147+
89148
scoped_lock::scoped_lock(lock_and_signal &lock)
90149
: lock(lock)
91150
{

trunk/src/rt/sync/lock_and_signal.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,31 @@
22
#ifndef LOCK_AND_SIGNAL_H
33
#define LOCK_AND_SIGNAL_H
44

5+
#ifndef RUST_NDEBUG
6+
#define DEBUG_LOCKS
7+
#endif
8+
59
class lock_and_signal {
610
#if defined(__WIN32__)
711
HANDLE _event;
812
CRITICAL_SECTION _cs;
13+
#if defined(DEBUG_LOCKS)
14+
DWORD _holding_thread;
15+
#endif
916
#else
1017
pthread_cond_t _cond;
1118
pthread_mutex_t _mutex;
19+
#if defined(DEBUG_LOCKS)
20+
pthread_t _holding_thread;
21+
#endif
1222
#endif
1323

24+
#if defined(DEBUG_LOCKS)
25+
bool lock_held_by_current_thread();
26+
#endif
27+
28+
void must_not_be_locked();
29+
1430
public:
1531
lock_and_signal();
1632
virtual ~lock_and_signal();
@@ -19,6 +35,9 @@ class lock_and_signal {
1935
void unlock();
2036
void wait();
2137
void signal();
38+
39+
void must_have_lock();
40+
void must_not_have_lock();
2241
};
2342

2443
class scoped_lock {

0 commit comments

Comments
 (0)