Revert "rt: Remove lock_held_by_current_thread"
Adds back the ability to make assertions about locks, but only under the
--enable-debug configuration
This reverts commit b247de6458.
Conflicts:
src/rt/rust_sched_loop.cpp
This commit is contained in:
@@ -389,6 +389,34 @@
|
|||||||
fun:uv_loop_delete
|
fun:uv_loop_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
lock_and_signal-probably-threadsafe-access-outside-of-lock
|
||||||
|
Helgrind:Race
|
||||||
|
fun:_ZN15lock_and_signal27lock_held_by_current_threadEv
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
lock_and_signal-probably-threadsafe-access-outside-of-lock2
|
||||||
|
Helgrind:Race
|
||||||
|
fun:_ZN15lock_and_signal6unlockEv
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
lock_and_signal-probably-threadsafe-access-outside-of-lock3
|
||||||
|
Helgrind:Race
|
||||||
|
fun:_ZN15lock_and_signal4lockEv
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
lock_and_signal-probably-threadsafe-access-outside-of-lock4
|
||||||
|
Helgrind:Race
|
||||||
|
fun:_ZN15lock_and_signal4waitEv
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
uv-async-send-does-racy-things
|
uv-async-send-does-racy-things
|
||||||
Helgrind:Race
|
Helgrind:Race
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ void
|
|||||||
rust_port_selector::msg_sent_on(rust_port *port) {
|
rust_port_selector::msg_sent_on(rust_port *port) {
|
||||||
rust_task *task = port->task;
|
rust_task *task = port->task;
|
||||||
|
|
||||||
|
port->lock.must_not_have_lock();
|
||||||
|
|
||||||
// Prevent two ports from trying to wake up the task
|
// Prevent two ports from trying to wake up the task
|
||||||
// simultaneously
|
// simultaneously
|
||||||
scoped_lock with(rendezvous_lock);
|
scoped_lock with(rendezvous_lock);
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ rust_sched_loop::number_of_live_tasks() {
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rust_sched_loop::reap_dead_tasks() {
|
rust_sched_loop::reap_dead_tasks() {
|
||||||
|
lock.must_have_lock();
|
||||||
|
|
||||||
if (dead_task == NULL) {
|
if (dead_task == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ rust_task::must_fail_from_being_killed() {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
rust_task::must_fail_from_being_killed_unlocked() {
|
rust_task::must_fail_from_being_killed_unlocked() {
|
||||||
|
kill_lock.must_have_lock();
|
||||||
return killed && !reentered_rust_stack;
|
return killed && !reentered_rust_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,15 @@
|
|||||||
|
|
||||||
#include "lock_and_signal.h"
|
#include "lock_and_signal.h"
|
||||||
|
|
||||||
|
// FIXME: This is not a portable way of specifying an invalid pthread_t
|
||||||
|
#define INVALID_THREAD 0
|
||||||
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
lock_and_signal::lock_and_signal()
|
lock_and_signal::lock_and_signal()
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
: _holding_thread(INVALID_THREAD)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
@@ -30,6 +37,9 @@ lock_and_signal::lock_and_signal()
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
lock_and_signal::lock_and_signal()
|
lock_and_signal::lock_and_signal()
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
: _holding_thread(INVALID_THREAD)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
CHECKED(pthread_cond_init(&_cond, NULL));
|
CHECKED(pthread_cond_init(&_cond, NULL));
|
||||||
CHECKED(pthread_mutex_init(&_mutex, NULL));
|
CHECKED(pthread_mutex_init(&_mutex, NULL));
|
||||||
@@ -47,14 +57,25 @@ lock_and_signal::~lock_and_signal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void lock_and_signal::lock() {
|
void lock_and_signal::lock() {
|
||||||
|
must_not_have_lock();
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
EnterCriticalSection(&_cs);
|
EnterCriticalSection(&_cs);
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
_holding_thread = GetCurrentThreadId();
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
CHECKED(pthread_mutex_lock(&_mutex));
|
CHECKED(pthread_mutex_lock(&_mutex));
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
_holding_thread = pthread_self();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void lock_and_signal::unlock() {
|
void lock_and_signal::unlock() {
|
||||||
|
must_have_lock();
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
_holding_thread = INVALID_THREAD;
|
||||||
|
#endif
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
LeaveCriticalSection(&_cs);
|
LeaveCriticalSection(&_cs);
|
||||||
#else
|
#else
|
||||||
@@ -66,12 +87,24 @@ void lock_and_signal::unlock() {
|
|||||||
* Wait indefinitely until condition is signaled.
|
* Wait indefinitely until condition is signaled.
|
||||||
*/
|
*/
|
||||||
void lock_and_signal::wait() {
|
void lock_and_signal::wait() {
|
||||||
|
must_have_lock();
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
_holding_thread = INVALID_THREAD;
|
||||||
|
#endif
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
LeaveCriticalSection(&_cs);
|
LeaveCriticalSection(&_cs);
|
||||||
WaitForSingleObject(_event, INFINITE);
|
WaitForSingleObject(_event, INFINITE);
|
||||||
EnterCriticalSection(&_cs);
|
EnterCriticalSection(&_cs);
|
||||||
|
must_not_be_locked();
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
_holding_thread = GetCurrentThreadId();
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
CHECKED(pthread_cond_wait(&_cond, &_mutex));
|
CHECKED(pthread_cond_wait(&_cond, &_mutex));
|
||||||
|
must_not_be_locked();
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
_holding_thread = pthread_self();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +119,32 @@ void lock_and_signal::signal() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
bool lock_and_signal::lock_held_by_current_thread()
|
||||||
|
{
|
||||||
|
#if defined(__WIN32__)
|
||||||
|
return _holding_thread == GetCurrentThreadId();
|
||||||
|
#else
|
||||||
|
return pthread_equal(_holding_thread, pthread_self());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
void lock_and_signal::must_have_lock() {
|
||||||
|
assert(lock_held_by_current_thread() && "must have lock");
|
||||||
|
}
|
||||||
|
void lock_and_signal::must_not_have_lock() {
|
||||||
|
assert(!lock_held_by_current_thread() && "must not have lock");
|
||||||
|
}
|
||||||
|
void lock_and_signal::must_not_be_locked() {
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void lock_and_signal::must_have_lock() { }
|
||||||
|
void lock_and_signal::must_not_have_lock() { }
|
||||||
|
void lock_and_signal::must_not_be_locked() { }
|
||||||
|
#endif
|
||||||
|
|
||||||
scoped_lock::scoped_lock(lock_and_signal &lock)
|
scoped_lock::scoped_lock(lock_and_signal &lock)
|
||||||
: lock(lock)
|
: lock(lock)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,14 +2,30 @@
|
|||||||
#ifndef LOCK_AND_SIGNAL_H
|
#ifndef LOCK_AND_SIGNAL_H
|
||||||
#define LOCK_AND_SIGNAL_H
|
#define LOCK_AND_SIGNAL_H
|
||||||
|
|
||||||
|
#ifndef RUST_NDEBUG
|
||||||
|
#define DEBUG_LOCKS
|
||||||
|
#endif
|
||||||
|
|
||||||
class lock_and_signal {
|
class lock_and_signal {
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
HANDLE _event;
|
HANDLE _event;
|
||||||
CRITICAL_SECTION _cs;
|
CRITICAL_SECTION _cs;
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
DWORD _holding_thread;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
pthread_cond_t _cond;
|
pthread_cond_t _cond;
|
||||||
pthread_mutex_t _mutex;
|
pthread_mutex_t _mutex;
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
pthread_t _holding_thread;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(DEBUG_LOCKS)
|
||||||
|
bool lock_held_by_current_thread();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void must_not_be_locked();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
lock_and_signal();
|
lock_and_signal();
|
||||||
@@ -19,6 +35,9 @@ public:
|
|||||||
void unlock();
|
void unlock();
|
||||||
void wait();
|
void wait();
|
||||||
void signal();
|
void signal();
|
||||||
|
|
||||||
|
void must_have_lock();
|
||||||
|
void must_not_have_lock();
|
||||||
};
|
};
|
||||||
|
|
||||||
class scoped_lock {
|
class scoped_lock {
|
||||||
|
|||||||
Reference in New Issue
Block a user