add new System::Monitor::waitAndClearInterrupted method

We had be using System::Monitor::wait to block threads internally in
the VM as well as to implement Object.wait.  However, the interrupted
flag should only be cleared in the latter case, not the former.  This
commit adds a new method and changes the semantics of the old one in
order to acheive the desired behavior.
This commit is contained in:
Joel Dice 2011-07-12 18:01:17 -06:00
parent a2dca0dc62
commit 7a82ee6b38
4 changed files with 31 additions and 8 deletions

View File

@ -3036,7 +3036,7 @@ monitorWait(Thread* t, object monitor, int64_t time)
ENTER(t, Thread::IdleState);
interrupted = t->lock->wait(t->systemThread, time);
interrupted = t->lock->waitAndClearInterrupted(t->systemThread, time);
}
monitorAcquire(t, monitor, monitorNode);

View File

@ -286,7 +286,16 @@ class MySystem: public System {
}
}
virtual bool wait(System::Thread* context, int64_t time) {
virtual void wait(System::Thread* context, int64_t time) {
wait(context, time, false);
}
virtual bool waitAndClearInterrupted(System::Thread* context, int64_t time)
{
return wait(context, time, true);
}
bool wait(System::Thread* context, int64_t time, bool clearInterrupted) {
Thread* t = static_cast<Thread*>(context);
if (owner_ == t) {
@ -298,7 +307,9 @@ class MySystem: public System {
{ ACQUIRE(t->mutex);
if (t->r->interrupted()) {
t->r->setInterrupted(false);
if (clearInterrupted) {
t->r->setInterrupted(false);
}
return true;
}
@ -329,7 +340,7 @@ class MySystem: public System {
t->flags = 0;
interrupted = t->r->interrupted();
if (interrupted) {
if (interrupted and clearInterrupted) {
t->r->setInterrupted(false);
}
}

View File

@ -60,7 +60,8 @@ class System {
virtual bool tryAcquire(Thread* context) = 0;
virtual void acquire(Thread* context) = 0;
virtual void release(Thread* context) = 0;
virtual bool wait(Thread* context, int64_t time) = 0;
virtual void wait(Thread* context, int64_t time) = 0;
virtual bool waitAndClearInterrupted(Thread* context, int64_t time) = 0;
virtual void notify(Thread* context) = 0;
virtual void notifyAll(Thread* context) = 0;
virtual Thread* owner() = 0;

View File

@ -247,7 +247,16 @@ class MySystem: public System {
}
}
virtual bool wait(System::Thread* context, int64_t time) {
virtual void wait(System::Thread* context, int64_t time) {
wait(context, time, false);
}
virtual bool waitAndClearInterrupted(System::Thread* context, int64_t time)
{
return wait(context, time, true);
}
bool wait(System::Thread* context, int64_t time, bool clearInterrupted) {
Thread* t = static_cast<Thread*>(context);
assert(s, t);
@ -262,7 +271,9 @@ class MySystem: public System {
{ ACQUIRE(s, t->mutex);
if (t->r->interrupted()) {
t->r->setInterrupted(false);
if (clearInterrupted) {
t->r->setInterrupted(false);
}
return true;
}
@ -294,7 +305,7 @@ class MySystem: public System {
t->flags = 0;
interrupted = t->r->interrupted();
if (interrupted) {
if (interrupted and clearInterrupted) {
t->r->setInterrupted(false);
}
}