summaryrefslogtreecommitdiffstats
path: root/python/service.py
diff options
context:
space:
mode:
authorRobert McQueen <robot101@debian.org>2005-11-07 12:14:53 +0000
committerRobert McQueen <robot101@debian.org>2005-11-07 12:14:53 +0000
commit95f9771d6be677d3393aab60f0f56126fbb252a6 (patch)
treef6d4226a29aaff30f72b9599b38e2aa4327ac46f /python/service.py
parentac36149533cdf3131dec3f43a7e9ea1ee11937f5 (diff)
2005-11-07 Robert McQueen <robot101@debian.org>
* python/_dbus.py: Add WeakReferenceDictionary cache of dbus.Bus instances to stop madness of creating new instances representing the same bus connection all the time, rendering any tracking of match rules and bus names quite meaningless. Caught a bug where the private argument to SessionBus() and friends was being passed in as use_default_mainloop by mistake. Still some problems with multiple dbus_binding.Connection instances representing the same low-level connection (eg when you use both SessionBus() and StarterBus() in same process), but it's a lot better now than it was. * python/dbus_bindings.pyx: Add constants with the return values for bus_request_name(). * python/service.py: Store bus name instances in a per-dbus.Bus cache and retrieve the same instances for the same name, so deletion can be done with refcounting. Also now throws some kind of error if you don't actually get the name you requested, unlike previously... * test/python/test-client.py: Add tests for instance caching of buses and bus name objects.
Diffstat (limited to 'python/service.py')
-rw-r--r--python/service.py62
1 files changed, 52 insertions, 10 deletions
diff --git a/python/service.py b/python/service.py
index 14a2d6d3..d1973b04 100644
--- a/python/service.py
+++ b/python/service.py
@@ -6,19 +6,60 @@ from exceptions import UnknownMethodException
from decorators import method
from decorators import signal
-class BusName:
+class BusName(object):
"""A base class for exporting your own Named Services across the Bus
"""
- def __init__(self, named_service, bus=None):
- self._named_service = named_service
-
+ def __new__(cls, name, bus=None):
+ # get default bus
if bus == None:
- # Get the default bus
- self._bus = _dbus.Bus()
+ bus = _dbus.Bus()
+
+ # see if this name is already defined, return it if so
+ if name in bus._bus_names:
+ return bus._bus_names[name]
+
+ # otherwise register the name
+ retval = dbus_bindings.bus_request_name(bus.get_connection(), name)
+ print retval
+ # TODO: more intelligent tracking of bus name states?
+ if retval == dbus_bindings.REQUEST_NAME_REPLY_PRIMARY_OWNER:
+ pass
+ elif retval == dbus_bindings.REQUEST_NAME_REPLY_IN_QUEUE:
+ # you can't arrive at this state via the high-level bindings
+ # because you can't put flags in, but... who knows?
+ print "joined queue for %s" % name
+ pass
+ elif retval == dbus_bindings.REQUEST_NAME_REPLY_EXISTS:
+ raise dbus_bindings.DBusException('requested name %s already exists' % name)
+ elif retval == dbus_bindings.REQUEST_NAME_REPLY_ALREADY_OWNER:
+ # if this is a shared bus which is being used by someone
+ # else in this process, this can happen legitimately
+ print "already owner of %s" % name
+ pass
else:
- self._bus = bus
+ raise dbus_bindings.DBusException('requesting name %s returned unexpected value %s' % (name, retval))
- dbus_bindings.bus_request_name(self._bus.get_connection(), named_service)
+ # and create the object
+ bus_name = object.__new__(cls)
+ bus_name._bus = bus
+ bus_name._name = name
+
+ # cache instance
+ bus._bus_names[name] = bus_name
+
+ return bus_name
+
+ # do nothing because this is called whether or not the bus name
+ # object was retrieved from the cache or created new
+ def __init__(self, *args, **keywords):
+ pass
+
+ # we can delete the low-level name here because these objects
+ # are guaranteed to exist only once for each bus name
+ def __del__(self):
+ # FIXME: we don't have this function yet :)
+ #dbus_bindings.bus_release_name(self._bus.get_connection(), self._named_service)
+ pass
def get_bus(self):
"""Get the Bus this Service is on"""
@@ -26,10 +67,10 @@ class BusName:
def get_name(self):
"""Get the name of this service"""
- return self._named_service
+ return self._name
def __repr__(self):
- return '<dbus.service.BusName %s on %r at %#x>' % (self._named_service, self._bus, id(self))
+ return '<dbus.service.BusName %s on %r at %#x>' % (self._name, self._bus, id(self))
__str__ = __repr__
@@ -322,3 +363,4 @@ class Object(Interface):
def __repr__(self):
return '<dbus.service.Object %s on %r at %#x>' % (self._object_path, self._name, id(self))
__str__ = __repr__
+