diff options
| -rw-r--r-- | src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java | 29 | ||||
| -rw-r--r-- | src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java | 49 |
2 files changed, 76 insertions, 2 deletions
diff --git a/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java b/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java index 60cde19..1c67014 100644 --- a/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java +++ b/src/com/isode/stroke/filetransfer/IncomingJingleFileTransfer.java @@ -110,12 +110,38 @@ public class IncomingJingleFileTransfer extends JingleFileTransfer implements In @Override public void call() { handleWaitOnHashTimerTicked(); } }); } + + @Override + protected void finalize() throws Throwable { + try { + destroy(); + } + finally { + super.finalize(); + } + } + + /** + * This replaces the C++ destructor. After calling this object should not be used again. + * If any methods are called after they behaviour is undefined and they may throw expections. + */ + public void destroy() { + if (waitOnHashTimerTickedConnection != null) { + waitOnHashTimerTickedConnection.disconnect(); + waitOnHashTimerTickedConnection = null; + } + if (waitOnHashTimer != null) { + waitOnHashTimer.stop(); + waitOnHashTimer = null; + } + hashCalculator = null; + } /** * IncomingFileTransferMethod. */ @Override public void accept(WriteBytestream stream) { @@ -491,12 +517,15 @@ public class IncomingJingleFileTransfer extends JingleFileTransfer implements In logger_.fine("Unknown hash, skipping\n"); return true; } } private void handleWaitOnHashTimerTicked() { + if (waitOnHashTimer == null) { + return; + } logger_.fine("\n"); waitOnHashTimer.stop(); terminate(JinglePayload.Reason.Type.Success); } private void handleTransferFinished(FileTransferError error) { diff --git a/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java b/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java index f32821b..aa38022 100644 --- a/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java +++ b/src/com/isode/stroke/filetransfer/OutgoingJingleFileTransfer.java @@ -85,12 +85,22 @@ public class OutgoingJingleFileTransfer extends JingleFileTransfer implements Ou private Timer waitForRemoteTermination; private SignalConnection processedBytesConnection; private SignalConnection transferFinishedConnection; private Logger logger_ = Logger.getLogger(this.getClass().getName()); + + /** + * Connection to {@link Timer#onTick} of {@link #waitForRemoteTermination} + */ + private final SignalConnection onTickConnection; + + /** + * Connection to {@link ReadBytestream#onRead} of {@link #stream} + */ + private SignalConnection streamReadConnection; public OutgoingJingleFileTransfer( final JID toJID, JingleSession session, ReadBytestream stream, FileTransferTransporterFactory transporterFactory, @@ -109,26 +119,58 @@ public class OutgoingJingleFileTransfer extends JingleFileTransfer implements Ou this.internalState = State.Initial; this.candidateAcknowledged = false; setFileInfo(fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription()); // calculate both, MD5 and SHA-1 since we don't know which one the other side supports hashCalculator = new IncrementalBytestreamHashCalculator(true, true, crypto); - stream.onRead.connect(new Slot1<ByteArray>() { + streamReadConnection = stream.onRead.connect(new Slot1<ByteArray>() { @Override public void call(ByteArray b) { + if (hashCalculator == null) { + return; + } hashCalculator.feedData(b); } }); waitForRemoteTermination = timerFactory.createTimer(5000); - waitForRemoteTermination.onTick.connect(new Slot() { + onTickConnection = waitForRemoteTermination.onTick.connect(new Slot() { @Override public void call() { handleWaitForRemoteTerminationTimeout(); } }); } + + @Override + protected void finalize() throws Throwable { + try { + destroy(); + } + finally { + super.finalize(); + } + } + + /** + * This replaces the C++ destructor. After calling this object should not be used again. + * If any methods are called after they behaviour is undefined and they may throw expections. + */ + public void destroy() { + if (onTickConnection != null) { + onTickConnection.disconnect(); + } + if (waitForRemoteTermination != null) { + waitForRemoteTermination.stop(); + waitForRemoteTermination = null; + } + if (streamReadConnection != null) { + streamReadConnection.disconnect(); + } + hashCalculator = null; + removeTransporter(); + } /** * OutgoingFileTransferMethod. */ @Override public void start() { @@ -380,12 +422,15 @@ public class OutgoingJingleFileTransfer extends JingleFileTransfer implements Ou protected TransportSession createRemoteCandidateSession() { return transporter.createRemoteCandidateSession(stream, ourCandidateChoice); } private void handleWaitForRemoteTerminationTimeout() { + if (waitForRemoteTermination == null) { + return; + } assert(internalState.equals(State.WaitForTermination)); logger_.warning("Other party did not terminate session. Terminate it now.\n"); waitForRemoteTermination.stop(); terminate(JinglePayload.Reason.Type.MediaError); } |
Swift