[telepathy-ashes/master] Initial work at disposing of dead things. I think I'm still leaking things though.

David Laban david.laban at collabora.co.uk
Sat Oct 24 06:45:54 PDT 2009


---
 ashes/tools/bases.py        |   10 +++++++++-
 ashes/tools/dispatchers.py  |   15 +++++++++------
 ashes/tools/media_echoer.py |   34 +++++++++++++++++++++-------------
 3 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/ashes/tools/bases.py b/ashes/tools/bases.py
index e291e34..5e617ed 100644
--- a/ashes/tools/bases.py
+++ b/ashes/tools/bases.py
@@ -24,6 +24,7 @@ class ObjectListener(object):
         self.dbus_object = dbus_object
         self.service_name = dbus_object.service_name
         self.object_path = dbus_object.object_path
+        self.signal_matches = []
 
     def __eq__(self, other):
         """
@@ -62,7 +63,8 @@ class ObjectListener(object):
         iface = self.dbus_object[iface_name]
         cb = getattr(self, signal_name, None)
         if cb:
-            iface.connect_to_signal(signal_name, cb)
+            signal_match = iface.connect_to_signal(signal_name, cb)
+            self.signal_matches.append(signal_match)
         else:
             # FIXME: actually decide how to configure debug messages.
             if "signals" in os.environ.get("TPPY_DEBUG", ""):
@@ -243,4 +245,10 @@ class ChannelListener(ObjectListener):
                 for signal_name in signal_names:
                     self.connect_to_signal(channel_type, signal_name)
 
+    def Closed(self):
+        for signal_match in self.signal_matches:
+            signal_match.remove()
+        self.signal_matches = []
+        self.parent = None
+
 
diff --git a/ashes/tools/dispatchers.py b/ashes/tools/dispatchers.py
index ce7a8dc..50f4739 100644
--- a/ashes/tools/dispatchers.py
+++ b/ashes/tools/dispatchers.py
@@ -32,9 +32,9 @@ class ChannelDispatcher(ConnectionListener):
     # instance variable later. This is massively confusing.
     _handler_classes = {}
 
-    # This list really is a class variable. The reason for this is to avoid
-    # two instances of the dispatcher handling the same channel.
-    channels = []
+    def __init__(self, *args, **kwargs):
+        self.channels = {}
+        super(ChannelDispatcher, self).__init__(*args, **kwargs)
 
     def _collect_handler_classes(self):
         """
@@ -115,6 +115,9 @@ class ChannelDispatcher(ConnectionListener):
         for object_path, properties in Channels:
             self._new_channel(object_path, properties)
 
+    def ChannelClosed(self, object_path):
+        del self.channels[object_path]
+
     def _new_channel(self, object_path, properties, handler_class=None):
         """
         Gets called for each new channel in NewChannels, and also as the reply
@@ -151,18 +154,18 @@ class ChannelDispatcher(ConnectionListener):
             else:
                 print id, 'does not match', contact_regexp
                 return
-        if channel in self.channels:
+        if channel in self.channels.values():
             print "Channel already handled:", channel.object_path
             return
 
         if handler_class is not None:
             # FIXME: split this out into its own function.
             handler = handler_class(self, channel, properties)
-            self.channels.append(handler)
+            self.channels[channel.object_path] = handler
         elif (channel_type, handle_type) in self._handler_classes:
             handler_class = self._handler_classes[channel_type, handle_type]
             handler = handler_class(self, channel, properties)
-            self.channels.append(handler)
+            self.channels[channel.object_path] = handler
             return handler
         else:
             print "Don't know how to handle channel with handle type:", handle_type,
diff --git a/ashes/tools/media_echoer.py b/ashes/tools/media_echoer.py
index 74b9ecb..638b106 100644
--- a/ashes/tools/media_echoer.py
+++ b/ashes/tools/media_echoer.py
@@ -4,9 +4,10 @@
 # /usr/lib/python2.6/dist-packages, but the ubuntu ppa versions of farsight
 # and tpfarsight install to /usr/lib/python2.6/site-packages
 import sys
+sys.path.append('/usr/lib/python2.6/site-packages')
 
+import gobject
 import dbus
-sys.path.append('/usr/lib/python2.6/site-packages')
 import tpfarsight
 import farsight
 import gst
@@ -36,17 +37,15 @@ class MediaChannelEchoer(MemberAcceptor):
                                             self.connection.object_path,
                                             channel.object_path)
 
-
-
-        self.fschannel = None
         self.pipeline = gst.Pipeline()
-        self.pipeline.get_bus().add_watch(self.async_handler)
+        self.watch_id = self.pipeline.get_bus().add_watch(self.async_handler)
 
         self.tfchannel.connect("session-created", self.session_created)
         self.tfchannel.connect("stream-created", self.stream_created)
         self.tfchannel.connect("stream-get-codec-config", self.stream_get_codec_config)
 
 
+
     #The following functions are copied from the call.py example and documented.
     def async_handler(self, bus, message):
         """
@@ -81,6 +80,7 @@ class MediaChannelEchoer(MemberAcceptor):
         Sets up self.src_pad_added to handle incoming media pads, so that
         media can be echoed back.
         """
+        self.stream = stream
         stream.connect("src-pad-added", self.src_pad_added)
         print green('Waiting for incoming audio/video.')
 
@@ -122,14 +122,22 @@ class MediaChannelEchoer(MemberAcceptor):
         #codecs = []
         return codecs
 
-    #def session_created(self, *args):
-    #    print green('session_created(%s)' % ', '.join(map(str, args)))
-    #def stream_created(self, channel, stream):
-    #    print green('stream_created(%s)' % ', '.join(map(str, [channel, stream])))
-    #def stream_get_codec_config(self, *args):
-    #    print green('stream-get-codec-config(%s)' % ', '.join(map(str, args)))
-
-
+    def Closed(self):
+        # FIXME: work out why there is a "loop detected in the graph of bin
+        # pipeline0!!", and why that's causing async_handler to stay alive.
+        gst.xml_write_file(self.pipeline, open('pipeline.xml', 'w'))
+        gobject.source_remove(self.watch_id)
+        bus = self.pipeline.get_bus().remove_signal_watch()
+        self.pipeline.set_state(gst.STATE_NULL)
+        # Remove refs to gstreamer and farsight objects and hope they die.
+        # Turns out they mostly do, but 
+        self.tfchannel = None
+        self.stream = None
+        self.pipeline = None
+        super(MediaChannelEchoer, self).Closed()
+
+    def __del__(self):
+        print "SUCCESS!: %s successfully destroyed." % self.object_path
 
 
 
-- 
1.5.6.5




More information about the telepathy-commits mailing list