From d91f96b5e2477bdbedbdd486ee153fe91fb43640 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Thu, 8 Dec 2011 00:06:05 +0000
Subject: [PATCH] Close the writer when the reader closes; only dispose of the
 connection once.

---
 .../transport/batch/OutgoingBatchConnection.java |  3 +--
 .../briar/transport/stream/StreamConnection.java | 16 +++++++++-------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java b/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java
index 562c5b3fe7..57b45b3fa3 100644
--- a/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java
+++ b/components/net/sf/briar/transport/batch/OutgoingBatchConnection.java
@@ -89,6 +89,7 @@ class OutgoingBatchConnection {
 			}
 			// Flush the output stream
 			out.flush();
+			transport.dispose(true);
 		} catch(DbException e) {
 			if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
 			transport.dispose(false);
@@ -96,7 +97,5 @@ class OutgoingBatchConnection {
 			if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
 			transport.dispose(false);
 		}
-		// Success
-		transport.dispose(true);
 	}
 }
diff --git a/components/net/sf/briar/transport/stream/StreamConnection.java b/components/net/sf/briar/transport/stream/StreamConnection.java
index c96467e6ce..cfbf1f224c 100644
--- a/components/net/sf/briar/transport/stream/StreamConnection.java
+++ b/components/net/sf/briar/transport/stream/StreamConnection.java
@@ -67,7 +67,7 @@ abstract class StreamConnection implements DatabaseListener {
 	protected final StreamTransportConnection transport;
 
 	private final Executor dbExecutor, verificationExecutor;
-	private final AtomicBoolean canSendOffer;
+	private final AtomicBoolean canSendOffer, disposed;
 	private final BlockingQueue<Runnable> writerTasks;
 
 	private Collection<MessageId> offered = null; // Locking: this
@@ -91,6 +91,7 @@ abstract class StreamConnection implements DatabaseListener {
 		this.contactId = contactId;
 		this.transport = transport;
 		canSendOffer = new AtomicBoolean(false);
+		disposed = new AtomicBoolean(false);
 		writerTasks = new LinkedBlockingQueue<Runnable>();
 	}
 
@@ -164,13 +165,14 @@ abstract class StreamConnection implements DatabaseListener {
 					throw new FormatException();
 				}
 			}
-			transport.dispose(true);
+			writerTasks.add(CLOSE);
+			if(!disposed.getAndSet(true)) transport.dispose(true);
 		} catch(DbException e) {
 			if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
-			transport.dispose(false);
+			if(!disposed.getAndSet(true)) transport.dispose(false);
 		} catch(IOException e) {
 			if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
-			transport.dispose(false);
+			if(!disposed.getAndSet(true)) transport.dispose(false);
 		}
 	}
 
@@ -205,13 +207,13 @@ abstract class StreamConnection implements DatabaseListener {
 					Thread.currentThread().interrupt();
 				}
 			}
-			transport.dispose(true);
+			if(!disposed.getAndSet(true)) transport.dispose(true);
 		} catch(DbException e) {
 			if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
-			transport.dispose(false);
+			if(!disposed.getAndSet(true)) transport.dispose(false);
 		} catch(IOException e) {
 			if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
-			transport.dispose(false);
+			if(!disposed.getAndSet(true)) transport.dispose(false);
 		} finally {
 			db.removeListener(this);
 		}
-- 
GitLab