[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