1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-25 21:42:07 +01:00

Handle spurious interrupts in XMPPTCPConnection

Also remove unnecessary done() check in nextStreamElement() and remove
wrong comment in !instantShutdown branch. There is no mechanism to
forcible close the socket.
This commit is contained in:
Florian Schmaus 2014-10-28 13:50:13 +01:00
parent 765e83ca81
commit 92bc3452da

View file

@ -1292,6 +1292,13 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
return shutdownTimestamp != null; return shutdownTimestamp != null;
} }
private void throwNotConnectedExceptionIfDoneAndResumptionNotPossible() throws NotConnectedException {
if (done() && !isSmResumptionPossible()) {
// Don't throw a NotConnectedException is there is an resumable stream available
throw new NotConnectedException();
}
}
/** /**
* Sends the specified element to the server. * Sends the specified element to the server.
* *
@ -1299,16 +1306,20 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
* @throws NotConnectedException * @throws NotConnectedException
*/ */
protected void sendStreamElement(Element element) throws NotConnectedException { protected void sendStreamElement(Element element) throws NotConnectedException {
if (done() && !isSmResumptionPossible()) { throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
// Don't throw a NotConnectedException is there is an resumable stream available
throw new NotConnectedException();
}
boolean enqueued = false;
while (!enqueued) {
try { try {
queue.put(element); queue.put(element);
enqueued = true;
}
catch (InterruptedException e) {
throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
// If the method above did not throw, we have a spurious interrupt and we should try to enqueue the
// element again
LOGGER.log(Level.FINE, "Spurious interrupt", e);
} }
catch (InterruptedException ie) {
throw new NotConnectedException();
} }
} }
@ -1329,23 +1340,21 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
} }
/** /**
* Returns the next available element from the queue for writing. * Maybe return the next available element from the queue for writing. If the queue is shut down <b>or</b> a
* spurious interrupt occurs, <code>null</code> is returned. So it is important to check the 'done' condition in
* that case.
* *
* @return the next element for writing. * @return the next element for writing or null.
*/ */
private Element nextStreamElement() { private Element nextStreamElement() {
// TODO not sure if nextStreamElement and/or this done() condition still required.
// Couldn't this be done in writePackets too?
if (done()) {
return null;
}
Element packet = null; Element packet = null;
try { try {
packet = queue.take(); packet = queue.take();
} }
catch (InterruptedException e) { catch (InterruptedException e) {
// Do nothing if (!queue.isShutdown()) {
LOGGER.log(Level.FINER, "Spurious interrupt", e);
}
} }
return packet; return packet;
} }
@ -1391,9 +1400,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
} }
} }
if (!instantShutdown) { if (!instantShutdown) {
// Flush out the rest of the queue. If the queue is extremely large, it's // Flush out the rest of the queue.
// possible we won't have time to entirely flush it before the socket is forced
// closed by the shutdown process.
try { try {
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
Element packet = queue.remove(); Element packet = queue.remove();