Web lists-archives.com

Re: GDBusProxy missing bus signals during construction




Hi,

On 07/23/2015 05:01 PM, Roger James wrote:
> 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.)
I had a very similar problem using native GDbus/Glibmm and the only solution which helped me was to subscribe to signals *in advance*, i.e. before the proxy object is created. I would also be happy to know a better way.
> 
> 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'
> 
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list@xxxxxxxxx
> https://mail.gnome.org/mailman/listinfo/gtk-devel-list
_______________________________________________
gtk-devel-list mailing list
gtk-devel-list@xxxxxxxxx
https://mail.gnome.org/mailman/listinfo/gtk-devel-list