mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-24 23:32:05 +01:00
Make SynchronizationPoint interruptible
SMACK-632
This commit is contained in:
parent
4a16ab9329
commit
189f524195
3 changed files with 13 additions and 18 deletions
|
@ -132,7 +132,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void connectInternal() throws SmackException {
|
protected void connectInternal() throws SmackException, InterruptedException {
|
||||||
done = false;
|
done = false;
|
||||||
try {
|
try {
|
||||||
// Ensure a clean starting state
|
// Ensure a clean starting state
|
||||||
|
|
|
@ -19,8 +19,6 @@ package org.jivesoftware.smack;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.Lock;
|
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.NoResponseException;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
|
@ -30,8 +28,6 @@ import org.jivesoftware.smack.packet.PlainStreamElement;
|
||||||
|
|
||||||
public class SynchronizationPoint<E extends Exception> {
|
public class SynchronizationPoint<E extends Exception> {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(SynchronizationPoint.class.getName());
|
|
||||||
|
|
||||||
private final AbstractXMPPConnection connection;
|
private final AbstractXMPPConnection connection;
|
||||||
private final Lock connectionLock;
|
private final Lock connectionLock;
|
||||||
private final Condition condition;
|
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.
|
* 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 NoResponseException if there was no response marking the synchronization point as success or failed.
|
||||||
* @throws E if there was a failure
|
* @throws E if there was a failure
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
public void checkIfSuccessOrWaitOrThrow() throws NoResponseException, E {
|
public void checkIfSuccessOrWaitOrThrow() throws NoResponseException, E, InterruptedException {
|
||||||
checkIfSuccessOrWait();
|
checkIfSuccessOrWait();
|
||||||
if (state == State.Failure) {
|
if (state == State.Failure) {
|
||||||
throw failureException;
|
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.
|
* 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 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();
|
connectionLock.lock();
|
||||||
try {
|
try {
|
||||||
if (state == State.Success) {
|
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
|
* {@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
|
* 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}.
|
* 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());
|
long remainingWait = TimeUnit.MILLISECONDS.toNanos(connection.getPacketReplyTimeout());
|
||||||
while (state == State.RequestSent || state == State.Initial) {
|
while (state == State.RequestSent || state == State.Initial) {
|
||||||
try {
|
if (remainingWait <= 0) {
|
||||||
if (remainingWait <= 0) {
|
state = State.NoResponse;
|
||||||
state = State.NoResponse;
|
break;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
remainingWait = condition.awaitNanos(remainingWait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1239,6 +1239,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
/**
|
/**
|
||||||
* Shuts down the stanza(/packet) writer. Once this method has been called, no further
|
* Shuts down the stanza(/packet) writer. Once this method has been called, no further
|
||||||
* packets will be written to the server.
|
* packets will be written to the server.
|
||||||
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
void shutdown(boolean instant) {
|
void shutdown(boolean instant) {
|
||||||
instantShutdown = instant;
|
instantShutdown = instant;
|
||||||
|
@ -1247,7 +1248,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
try {
|
try {
|
||||||
shutdownDone.checkIfSuccessOrWait();
|
shutdownDone.checkIfSuccessOrWait();
|
||||||
}
|
}
|
||||||
catch (NoResponseException e) {
|
catch (NoResponseException | InterruptedException e) {
|
||||||
LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", e);
|
LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue