GDBusProxy missing bus signals during construction
- From: Roger James <roger beardandsandals co uk>
- To: gtk-devel-list gnome org
- Subject: GDBusProxy missing bus signals during construction
- Date: Thu, 23 Jul 2015 15:01:01 +0100
I am trying to implement a Zeroconf service browser using a PyGobject
Gio.DBusProxy object to talk to avahi. It all works fine but the browser
randomly misses the initial one or more ItemNew signals from the avahi
server. It sometimes even misses the AllForNow signal. Subsequent
ItemNew signals are seen OK as services come and go.
It appears that the problem is that the GLIb objects subscribes to the
dbus signals during the construction process (the DO_NOT_CONNECT_SIGNALS
is not set). It then notifies(GDbusProxy.new) or
returns(GDBusProxy.new_sync) to the calling object. Once I get the new
proxy object back I can use connect on the parent gobject to hook the
incoming dbus signal to my applications signal handling callback.
However any dbus signals that arrive from server (avahi) before that
connection is made are discarded. If set DO_NOT_CONNECT_SIGNALS I would
have mimic the whole of DBusProxy/DBUsConection's handling of dbus side
signal mapping. I don't want to have to do that. What am I missing?
Some fundamental questions are.
1. How can I stop this happening.
2. Is avahi breaking some sort of dbus protocol or convention in sending
these signals immediately a new bus connection is made?
3. Is the a flaw in the GDBusProxy design/documenation? (sorry guys, but
have spent a while looing at this.)
Thanks,
Roger
Here is my python code
#!/usr/bin/env python
from gi.repository import Gio, GLib, GObject, Gtk
import avahi
import signal
import time
class avahibrowser(Gio.Application):
def service_resolved(self, *args):
print 'service resolved'
print 'name:', args[2]
print 'address:', args[7]
print 'port:', args[8]
def print_error(self, *args):
print 'error_handler'
print args[0]
def browserCallback(self, proxy, sender, signal, args):
if signal == 'ItemNew':
# Arguments are [0] i interface, [1] i protocol [2] s name [3] s type [4] s domain [5] u flags
print "Found service '%s' type '%s' domain '%s' " % (args[2], args[3], args[4])
#self.avahiserver.ResolveService('iisssiu',
# args[0], # Interface
# args[1], # Protocol
# args[2], # Name
# args[3], # Service Type
# args[4], # Domain
# avahi.PROTO_UNSPEC, dbus.UInt32(0),
# reply_handler=self.service_resolved, error_handler=self.print_error)
else:
print 'signal', signal, 'arguments', args
def do_activate(self): # Define this to suppress glib warning
pass
def new_browser_proxy_callback(self, source_object, res, user_data):
#source_object.connect('g-signal', self.browserCallback)
self.avahibrowser = Gio.DBusProxy.new_finish(res)
self.avahibrowser.connect('g-signal', self.browserCallback)
def new_server_proxy_callback(self, source_object, res, user_data):
self.avahiserver = Gio.DBusProxy.new_finish(res)
avahibrowserpath = self.avahiserver.ServiceBrowserNew('(iissu)',
avahi.IF_UNSPEC,
avahi.PROTO_INET,
'_scratch._tcp',
'local',
0)
Gio.DBusProxy.new(self.systemDBusConnection, 0, None,
avahi.DBUS_NAME,
avahibrowserpath,
avahi.DBUS_INTERFACE_SERVICE_BROWSER, None,
self.new_browser_proxy_callback, None)
def bus_get_callback(self, source_object, res, user_data):
self.systemDBusConnection = Gio.bus_get_finish(res)
Gio.DBusProxy.new(self.systemDBusConnection, 0, None,
avahi.DBUS_NAME,
avahi.DBUS_PATH_SERVER,
avahi.DBUS_INTERFACE_SERVER, None,
self.new_server_proxy_callback, None)
# Gnome application initialization routine
def __init__(self, application_id, flags):
Gio.Application.__init__(self, application_id=application_id, flags=flags)
Gio.bus_get(Gio.BusType.SYSTEM, None, self.bus_get_callback, None)
def InitSignal(app):
def signal_action(signal):
if signal is 1:
print("Caught signal SIGHUP(1)")
elif signal is 2:
print("Caught signal SIGINT(2)")
elif signal is 15:
print("Caught signal SIGTERM(15)")
app.release()
def idle_handler(*args):
print("Python signal handler activated.")
GLib.idle_add(signal_action, priority=GLib.PRIORITY_HIGH)
def handler(*args):
print("GLib signal handler activated.")
signal_action(args[0])
def install_glib_handler(sig):
unix_signal_add = None
if hasattr(GLib, "unix_signal_add"):
unix_signal_add = GLib.unix_signal_add
elif hasattr(GLib, "unix_signal_add_full"):
unix_signal_add = GLib.unix_signal_add_full
if unix_signal_add:
print("Register GLib signal handler: %r" % sig)
unix_signal_add(GLib.PRIORITY_HIGH, sig, handler, sig)
else:
print("Can't install GLib signal handler, too old gi.")
SIGS = [getattr(signal, s, None) for s in "SIGINT SIGTERM SIGHUP".split()]
for sig in filter(None, SIGS):
print("Register Python signal handler: %r" % sig)
signal.signal(sig, idle_handler)
GLib.idle_add(install_glib_handler, sig, priority=GLib.PRIORITY_HIGH)
if __name__ == "__main__":
Application = avahibrowser("uk.co.beardandsandals.avahibrowser", Gio.ApplicationFlags.FLAGS_NONE)
# Set up python and Gio signal handling
InitSignal(Application)
Application.hold()
Application.run(None)
print 'Exiting'
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]