8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw

Reviewed-by: martin, psandoz
This commit is contained in:
Doug Lea 2017-12-02 10:03:41 -08:00
parent fad5094503
commit eac77274e8
4 changed files with 180 additions and 21 deletions

View file

@ -422,8 +422,8 @@ public abstract class AbstractQueuedLongSynchronizer
* @return {@code true} if interrupted while waiting
*/
final boolean acquireQueued(final Node node, long arg) {
boolean interrupted = false;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
@ -431,12 +431,13 @@ public abstract class AbstractQueuedLongSynchronizer
p.next = null; // help GC
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
if (shouldParkAfterFailedAcquire(p, node))
interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
if (interrupted)
selfInterrupt();
throw t;
}
}
@ -510,8 +511,8 @@ public abstract class AbstractQueuedLongSynchronizer
*/
private void doAcquireShared(long arg) {
final Node node = addWaiter(Node.SHARED);
boolean interrupted = false;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) {
@ -519,18 +520,18 @@ public abstract class AbstractQueuedLongSynchronizer
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
if (interrupted)
selfInterrupt();
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
if (shouldParkAfterFailedAcquire(p, node))
interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
throw t;
} finally {
if (interrupted)
selfInterrupt();
}
}

View file

@ -505,7 +505,7 @@ public abstract class AbstractQueuedSynchronizer
*
* @return the predecessor of this node
*/
final Node predecessor() throws NullPointerException {
final Node predecessor() {
Node p = prev;
if (p == null)
throw new NullPointerException();
@ -902,8 +902,8 @@ public abstract class AbstractQueuedSynchronizer
* @return {@code true} if interrupted while waiting
*/
final boolean acquireQueued(final Node node, int arg) {
boolean interrupted = false;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
@ -911,12 +911,13 @@ public abstract class AbstractQueuedSynchronizer
p.next = null; // help GC
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
if (shouldParkAfterFailedAcquire(p, node))
interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
if (interrupted)
selfInterrupt();
throw t;
}
}
@ -990,8 +991,8 @@ public abstract class AbstractQueuedSynchronizer
*/
private void doAcquireShared(int arg) {
final Node node = addWaiter(Node.SHARED);
boolean interrupted = false;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) {
@ -999,18 +1000,18 @@ public abstract class AbstractQueuedSynchronizer
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
if (interrupted)
selfInterrupt();
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
if (shouldParkAfterFailedAcquire(p, node))
interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
throw t;
} finally {
if (interrupted)
selfInterrupt();
}
}