From 372ab97ca0d217adf5be3b7930358c3930883f79 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Fri, 31 Jul 2009 15:25:33 +0000 Subject: [PATCH] Partially fixes a memory leak which used to retain CallDialog and just about anything related to a Call because MediaControl#sourceProcessor wasn't closed, it was just stopped. The fix works for calls with no video. Video calls though, at least on Linux, still leak the same objects but the cause is different (and I suspect civil to be erroneously not breaking a reference). --- .../communicator/impl/media/MediaControl.java | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/net/java/sip/communicator/impl/media/MediaControl.java b/src/net/java/sip/communicator/impl/media/MediaControl.java index 87767d4d8..4a48b9a7c 100644 --- a/src/net/java/sip/communicator/impl/media/MediaControl.java +++ b/src/net/java/sip/communicator/impl/media/MediaControl.java @@ -91,7 +91,7 @@ public class MediaControl * The processor that will be handling content coming from our capture data * sources. */ - public Processor sourceProcessor = null; + private Processor sourceProcessor = null; /** * The list of readers currently using our processor. @@ -200,8 +200,7 @@ public void propertyChange(PropertyChangeEvent evt) private void initCaptureDevices() throws MediaException { - if (avDataSource != null) - avDataSource.disconnect(); + disposeBeforeInitCaptureDevices(); // Init audio device CaptureDeviceInfo audioDeviceInfo @@ -286,6 +285,33 @@ else if (videoDataSource != null) sourceProcessor = null; } + /** + * Allows this instance to dispose of any state which is to reinitialized by + * {@link #initCaptureDevices()}. For example, a vital requirement is to + * invoke {@link Controller#close()} on sourceProcessor + * regardless of the fact that it is soon to not be referenced at all or it + * will keep unnecessary threads alive and they will in turn keep just about + * anything created to an associated Call. + */ + private void disposeBeforeInitCaptureDevices() + { + if (avDataSource != null) + avDataSource.disconnect(); + if (sourceProcessor != null) + { + sourceProcessor.stop(); + if (sourceProcessor.getState() == Processor.Realized) + { + DataSource dataOutput = sourceProcessor.getDataOutput(); + + if (dataOutput != null) + dataOutput.disconnect(); + } + sourceProcessor.deallocate(); + sourceProcessor.close(); + } + } + /** * Opens the source pointed to by the debugMediaSource URL and * prepares to use it instead of capture devices. @@ -973,9 +999,6 @@ public void stopProcessingMedia(Object reader) if( sourceProcessor.getState() == Processor.Started ) { - avDataSource.disconnect(); - sourceProcessor.stop(); - try { initCaptureDevices(); @@ -1158,19 +1181,6 @@ public void setLocalVideoAllowed(boolean allowed) { localVideoAllowed = allowed; - if (sourceProcessor != null) - { - sourceProcessor.stop(); - if (sourceProcessor.getState() == Processor.Realized) - { - DataSource dataOutput = sourceProcessor.getDataOutput(); - - if (dataOutput != null) - dataOutput.disconnect(); - } - sourceProcessor.deallocate(); - sourceProcessor.close(); - } initCaptureDevices(); } }