mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
fix Thread.interrupt deadlock
Previously, we returned immediately from Monitor.wait if we found we had been interrupted, but this caused deadlock when waiting to enter the exclusive state, since we never released Machine::stateLock to allow active threads to transition into the idle state. This commit ensures that we at least briefly release the lock without actually waiting in that case.
This commit is contained in:
parent
44f7bd9fe0
commit
8d2ca7aaf5
@ -306,12 +306,10 @@ class MySystem: public System {
|
||||
|
||||
{ ACQUIRE(t->mutex);
|
||||
|
||||
if (t->r->interrupted()) {
|
||||
if (clearInterrupted) {
|
||||
interrupted = t->r->interrupted();
|
||||
if (interrupted and clearInterrupted) {
|
||||
t->r->setInterrupted(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
t->flags |= Waiting;
|
||||
|
||||
@ -322,6 +320,7 @@ class MySystem: public System {
|
||||
owner_ = 0;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
if (not interrupted) {
|
||||
// pretend anything greater than one million years (in
|
||||
// milliseconds) is infinity so as to avoid overflow:
|
||||
if (time and time < INT64_C(31536000000000000)) {
|
||||
@ -335,16 +334,17 @@ class MySystem: public System {
|
||||
expect(s, rv == 0 or rv == EINTR);
|
||||
}
|
||||
|
||||
notified = ((t->flags & Notified) != 0);
|
||||
|
||||
t->flags = 0;
|
||||
|
||||
interrupted = t->r->interrupted();
|
||||
if (interrupted and clearInterrupted) {
|
||||
t->r->setInterrupted(false);
|
||||
}
|
||||
}
|
||||
|
||||
notified = ((t->flags & Notified) != 0);
|
||||
|
||||
t->flags = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
|
||||
if (not notified) {
|
||||
|
@ -270,12 +270,10 @@ class MySystem: public System {
|
||||
|
||||
{ ACQUIRE(s, t->mutex);
|
||||
|
||||
if (t->r->interrupted()) {
|
||||
if (clearInterrupted) {
|
||||
interrupted = t->r->interrupted();
|
||||
if (interrupted and clearInterrupted) {
|
||||
t->r->setInterrupted(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
t->flags |= Waiting;
|
||||
|
||||
@ -288,6 +286,7 @@ class MySystem: public System {
|
||||
bool success UNUSED = ReleaseMutex(mutex);
|
||||
assert(s, success);
|
||||
|
||||
if (not interrupted) {
|
||||
success = ResetEvent(t->event);
|
||||
assert(s, success);
|
||||
|
||||
@ -300,16 +299,17 @@ class MySystem: public System {
|
||||
r = WaitForSingleObject(t->mutex, INFINITE);
|
||||
assert(s, r == WAIT_OBJECT_0);
|
||||
|
||||
notified = ((t->flags & Notified) != 0);
|
||||
|
||||
t->flags = 0;
|
||||
|
||||
interrupted = t->r->interrupted();
|
||||
if (interrupted and clearInterrupted) {
|
||||
t->r->setInterrupted(false);
|
||||
}
|
||||
}
|
||||
|
||||
notified = ((t->flags & Notified) != 0);
|
||||
|
||||
t->flags = 0;
|
||||
}
|
||||
|
||||
r = WaitForSingleObject(mutex, INFINITE);
|
||||
assert(s, r == WAIT_OBJECT_0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user