Make SynchronizationPoint interruptible

SMACK-632
This commit is contained in:
Florian Schmaus 2015-04-12 18:33:43 +02:00
parent 4a16ab9329
commit 189f524195
3 changed files with 13 additions and 18 deletions

View File

@ -132,7 +132,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
}
@Override
protected void connectInternal() throws SmackException {
protected void connectInternal() throws SmackException, InterruptedException {
done = false;
try {
// Ensure a clean starting state

View File

@ -19,8 +19,6 @@ package org.jivesoftware.smack;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
@ -30,8 +28,6 @@ import org.jivesoftware.smack.packet.PlainStreamElement;
public class SynchronizationPoint<E extends Exception> {
private static final Logger LOGGER = Logger.getLogger(SynchronizationPoint.class.getName());
private final AbstractXMPPConnection connection;
private final Lock connectionLock;
private final Condition condition;
@ -120,8 +116,9 @@ public class SynchronizationPoint<E extends Exception> {
* Check if this synchronization point is successful or wait the connections reply timeout.
* @throws NoResponseException if there was no response marking the synchronization point as success or failed.
* @throws E if there was a failure
* @throws InterruptedException
*/
public void checkIfSuccessOrWaitOrThrow() throws NoResponseException, E {
public void checkIfSuccessOrWaitOrThrow() throws NoResponseException, E, InterruptedException {
checkIfSuccessOrWait();
if (state == State.Failure) {
throw failureException;
@ -131,8 +128,9 @@ public class SynchronizationPoint<E extends Exception> {
/**
* Check if this synchronization point is successful or wait the connections reply timeout.
* @throws NoResponseException if there was no response marking the synchronization point as success or failed.
* @throws InterruptedException
*/
public void checkIfSuccessOrWait() throws NoResponseException {
public void checkIfSuccessOrWait() throws NoResponseException, InterruptedException {
connectionLock.lock();
try {
if (state == State.Success) {
@ -222,20 +220,16 @@ public class SynchronizationPoint<E extends Exception> {
* {@link #reportSuccess()}, {@link #reportFailure()} and {@link #reportFailure(Exception)} will either set this
* synchronization point to {@link State#Success} or {@link State#Failure}. If none of them is set after the
* connections reply timeout, this method will set the state of {@link State#NoResponse}.
* @throws InterruptedException
*/
private void waitForConditionOrTimeout() {
private void waitForConditionOrTimeout() throws InterruptedException {
long remainingWait = TimeUnit.MILLISECONDS.toNanos(connection.getPacketReplyTimeout());
while (state == State.RequestSent || state == State.Initial) {
try {
if (remainingWait <= 0) {
state = State.NoResponse;
break;
}
remainingWait = condition.awaitNanos(remainingWait);
} catch (InterruptedException e) {
// This InterruptedException could be "spurious wakeups", see javadoc of awaitNanos()
LOGGER.log(Level.WARNING, "Thread interrupt while waiting for condition or timeout ignored", e);
if (remainingWait <= 0) {
state = State.NoResponse;
break;
}
remainingWait = condition.awaitNanos(remainingWait);
}
}

View File

@ -1239,6 +1239,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
/**
* Shuts down the stanza(/packet) writer. Once this method has been called, no further
* packets will be written to the server.
* @throws InterruptedException
*/
void shutdown(boolean instant) {
instantShutdown = instant;
@ -1247,7 +1248,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
try {
shutdownDone.checkIfSuccessOrWait();
}
catch (NoResponseException e) {
catch (NoResponseException | InterruptedException e) {
LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", e);
}
}