tweak System::Monitor::wait to avoid notify deadlock

This commit is contained in:
Joel Dice 2008-01-16 13:46:39 -07:00
parent f5f7b01689
commit 6ba7852a62
2 changed files with 86 additions and 73 deletions

View File

@ -274,7 +274,10 @@ class MySystem: public System {
Thread* t = static_cast<Thread*>(context);
if (owner_ == t) {
ACQUIRE(t->mutex);
bool interrupted;
unsigned depth;
{ ACQUIRE(t->mutex);
if (t->r->interrupted()) {
t->r->setInterrupted(false);
@ -285,7 +288,7 @@ class MySystem: public System {
append(t);
unsigned depth = this->depth;
depth = this->depth;
this->depth = 0;
owner_ = 0;
pthread_mutex_unlock(&mutex);
@ -301,10 +304,6 @@ class MySystem: public System {
expect(s, rv == 0 or rv == EINTR);
}
pthread_mutex_lock(&mutex);
owner_ = t;
this->depth = depth;
if ((t->flags & Notified) == 0) {
remove(t);
}
@ -314,10 +313,17 @@ class MySystem: public System {
if (t->r->interrupted()) {
t->r->setInterrupted(false);
return true;
interrupted = true;
} else {
return false;
interrupted = false;
}
}
pthread_mutex_lock(&mutex);
owner_ = t;
this->depth = depth;
return interrupted;
} else {
sysAbort(s);
}

View File

@ -240,7 +240,11 @@ class MySystem: public System {
assert(s, t);
if (owner_ == t) {
ACQUIRE(s, t->mutex);
bool interrupted;
unsigned depth;
int r UNUSED;
{ ACQUIRE(s, t->mutex);
if (t->r->interrupted()) {
t->r->setInterrupted(false);
@ -251,7 +255,7 @@ class MySystem: public System {
append(t);
unsigned depth = this->depth;
depth = this->depth;
this->depth = 0;
owner_ = 0;
@ -264,18 +268,12 @@ class MySystem: public System {
success = ReleaseMutex(t->mutex);
assert(s, success);
int r UNUSED = WaitForSingleObject(t->event, (time ? time : INFINITE));
r = WaitForSingleObject(t->event, (time ? time : INFINITE));
assert(s, r == WAIT_OBJECT_0 or r == WAIT_TIMEOUT);
r = WaitForSingleObject(t->mutex, INFINITE);
assert(s, r == WAIT_OBJECT_0);
r = WaitForSingleObject(mutex, INFINITE);
assert(s, r == WAIT_OBJECT_0);
owner_ = t;
this->depth = depth;
if ((t->flags & Notified) == 0) {
remove(t);
}
@ -285,10 +283,19 @@ class MySystem: public System {
if (t->r->interrupted()) {
t->r->setInterrupted(false);
return true;
interrupted = true;
} else {
return false;
interrupted = false;
}
}
r = WaitForSingleObject(mutex, INFINITE);
assert(s, r == WAIT_OBJECT_0);
owner_ = t;
this->depth = depth;
return interrupted;
} else {
sysAbort(s);
}