diff options
Diffstat (limited to 'src/main/java/de/pixart')
-rw-r--r-- | src/main/java/de/pixart/messenger/xml/TagWriter.java | 4 | ||||
-rw-r--r-- | src/main/java/de/pixart/messenger/xmpp/XmppConnection.java | 46 |
2 files changed, 33 insertions, 17 deletions
diff --git a/src/main/java/de/pixart/messenger/xml/TagWriter.java b/src/main/java/de/pixart/messenger/xml/TagWriter.java index 3f4d011a2..c6b84170d 100644 --- a/src/main/java/de/pixart/messenger/xml/TagWriter.java +++ b/src/main/java/de/pixart/messenger/xml/TagWriter.java @@ -26,7 +26,9 @@ public class TagWriter { try { AbstractStanza output = writeQueue.take(); outputStream.write(output.toString()); - outputStream.flush(); + if (writeQueue.size() == 0) { + outputStream.flush(); + } } catch (Exception e) { return; } diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java index f015544ed..b242cd568 100644 --- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java +++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java @@ -38,6 +38,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; @@ -149,6 +151,8 @@ public class XmppConnection implements Runnable { private SaslMechanism saslMechanism; private URL redirectionUrl = null; private String verifiedHostname = null; + private Thread mThread; + private CountDownLatch mStreamCountDownLatch; private class MyKeyManager implements X509KeyManager { @Override @@ -236,7 +240,8 @@ public class XmppConnection implements Runnable { protected void changeStatus(final Account.State nextStatus) { synchronized (this) { - if (Thread.currentThread().isInterrupted()) { + this.mThread = Thread.currentThread(); + if (this.mThread.isInterrupted()) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": not changing status to " + nextStatus + " because thread was interrupted"); return; } @@ -541,6 +546,8 @@ public class XmppConnection implements Runnable { } private void processStream() throws XmlPullParserException, IOException, NoSuchAlgorithmException { + final CountDownLatch streamCountDownLatch = new CountDownLatch(1); + this.mStreamCountDownLatch = streamCountDownLatch; Tag nextTag = tagReader.readTag(); while (nextTag != null && !nextTag.isEnd("stream")) { if (nextTag.isStart("error")) { @@ -710,6 +717,9 @@ public class XmppConnection implements Runnable { } nextTag = tagReader.readTag(); } + if (nextTag != null && nextTag.isEnd("stream")) { + streamCountDownLatch.countDown(); + } } private void acknowledgeStanzaUpTo(int serverCount) { @@ -1490,7 +1500,9 @@ public class XmppConnection implements Runnable { } public void interrupt() { - Thread.currentThread().interrupt(); + if (this.mThread != null) { + this.mThread.interrupt(); + } } public void disconnect(final boolean force) { @@ -1499,28 +1511,30 @@ public class XmppConnection implements Runnable { if (force) { forceCloseSocket(); } else { - if (tagWriter.isActive()) { - tagWriter.finish(); - final Socket currentSocket = socket; + final TagWriter currentTagWriter = this.tagWriter; + if (currentTagWriter.isActive()) { + currentTagWriter.finish(); + final Socket currentSocket = this.socket; + final CountDownLatch streamCountDownLatch = this.mStreamCountDownLatch; try { - for (int i = 0; i <= 10 && !tagWriter.finished() && !currentSocket.isClosed(); ++i) { - uninterruptedSleep(100); + for (int i = 0; i <= 10 && !currentTagWriter.finished() && !currentSocket.isClosed(); ++i) { + Thread.sleep(100); } Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": closing stream"); - tagWriter.writeTag(Tag.end("stream:stream")); - for (int i = 0; i <= 20 && !currentSocket.isClosed(); ++i) { - uninterruptedSleep(100); - } - if (currentSocket.isClosed()) { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": remote closed socket"); - } else { - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": remote has not closed socket. force closing"); + currentTagWriter.writeTag(Tag.end("stream:stream")); + if (streamCountDownLatch != null) { + if (streamCountDownLatch.await(1, TimeUnit.SECONDS)) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": remote ended stream"); + } else { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": remote has not closed socket. force closing"); + } } + } catch (InterruptedException e) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": interrupted while gracefully closing stream"); } catch (final IOException e) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": io exception during disconnect (" + e.getMessage() + ")"); } finally { FileBackend.close(currentSocket); - forceCloseSocket(); } } else { forceCloseSocket(); |