Thanks Simon.<br><br>Thanks for the extensive info; however it needs some hours (if not days :P) to be digested.<br><br><div class="gmail_quote">On Tue, Dec 25, 2012 at 9:24 PM, Simon McVittie <span dir="ltr"><<a href="mailto:simon.mcvittie@collabora.co.uk" target="_blank">simon.mcvittie@collabora.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On 24/12/12 08:26, Ajay Garg wrote:<br>
> For a recap of the brief history, I have a parent process, that is<br>
> spawning a child process via "subprocess".<br>
> Currently, the child-process is a GUI process; however, I intend to<br>
> "behave" it as a dbus-service as well.<br>
<br>
</div>In general that is something that can work, but it's necessary to<br>
understand a bit about how main loops work, and how the modules of your<br>
process deal with a main loop.<br>
<br>
Just saying "GUI" is not very informative: there are dozens of GUI<br>
frameworks that you might be using, each with their own requirements and<br>
oddities. If you say Gtk, or Qt, or Tk, or Windows MFC, or whatever<br>
specific GUI framework you're using, then it becomes possible to say<br>
something concrete about your situation.<br>
<br>
Based on later mails in the thread you seem to be using Gtk.<br>
<br>
I should note here that you seem to be using PyGtk (the "traditional"<br>
Gtk 2 Python binding), which is deprecated. The modern version is to use<br>
PyGI, the Python GObject-Introspection binding, and Gtk 3.<br>
<br>
When using PyGI, you have a choice of two D-Bus implementations: either<br>
GDBus (part of gi.repository.GIO), or dbus-python ("import dbus"). I<br>
would recommend GDBus, since dbus-python is constrained by backwards<br>
compatibility with some flawed design decisions.<br>
<br>
However, assuming you're stuck with dbus-python:<br>
<div class="im"><br>
> I then used composition, wherein another class, "RemoteListener"<br>
> deriving from "dbus.service.Object" was made an attribute of the "main"<br>
> class. That worked.<br>
> However, when I do<br>
><br>
> dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)<br>
> GObject.mainloop.run()<br>
><br>
> in the "RemoteListener"'s __init__ method, the GUI of the "main" class<br>
> fails to load (apparently, because the "mainloop.run()" causes the<br>
> singular, main-thread to go into busy-wait).<br>
<br>
</div>Almost; it's not a busy-wait. GObject.mainloop.run() is the equivalent<br>
of this pseudocode:<br>
<br>
def run(self):<br>
while not global_default_main_context.someone_has_called_quit:<br>
if global_default_main_context.has_more_events():<br>
global_default_main_context.process_next_event()<br>
else:<br>
global_default_main_context.wait_for_an_event()<br>
<br>
so it will loop until someone calls GObject.mainloop.quit() or<br>
equivalent, or forever if that never happens - but as long as nothing<br>
"interesting" happens, it will block on a poll() or select() syscall in<br>
what my pseudocode calls wait_for_an_event(), which is the right thing<br>
to do in event-driven programming like GLib/Gtk.<br>
<br>
(If you replace the last line of my pseudocode with "continue", that<br>
would be a busy-wait.)<br>
<div class="im"><br>
> I tried option b), but now instantiating "RemoteListener" in a separate<br>
> thread<br>
<br>
</div>It is unclear whether the dbus-glib main loop glue (as set up by<br>
DBusGMainLoop) is thread-safe or not. The safest assumption is always<br>
"if you don't know whether foo is thread-safe, it probably isn't". In<br>
any case, if it *is* thread-safe, the subset of it that's exposed<br>
through dbus-python isn't enough to use it in multiple threads.<br>
<br>
GDBus, as made available via PyGI (specifically, gi.repository.GIO), is<br>
known to be thread-safe.<br>
<div class="im"><br>
> Is there a way to run GUI and a dbus-service together?<br>
<br>
</div>The general answer: only if either the GUI and the D-Bus code<br>
run in different threads, or if they run in the same thread and can be<br>
made to share a main context.<br>
<br>
The specific answer for Gtk: yes, they can easily share a main context.<br>
<br>
This:<br>
<br>
> dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)<br>
<br>
sets up dbus-python's mainloop integration to integrate with the global<br>
default main-context in GLib (implementation detail: it currently uses<br>
dbus-glib to do that). What that means is that whenever a D-Bus<br>
connection started by dbus-python wants to listen for events on a<br>
socket, or wait for a timeout, it will ask GLib to add those to the<br>
global default main context as event sources.<br>
<br>
This:<br>
<br>
> GObject.mainloop.run()<br>
<br>
iterates GLib's global default main context, analogous to the pseudocode<br>
I mentioned before. Any "interesting" events that happen will cause your<br>
code to be executed.<br>
<br>
A typical GUI application also needs to run the main loop to<br>
wait for events. In PyGtk, you'd typically do that with:<br>
<br>
> Gtk.main()<br>
<br>
Gtk also uses GLib's global default main context, so this is pretty<br>
similar to GObject.mainloop.run() - if you just remove the call to<br>
GObject.mainloop.run() and use Gtk.main() instead, everything should be<br>
fine.<br>
<br>
> As per <a href="http://www.pygtk.org/pygtk2reference/class-" target="_blank">http://www.pygtk.org/pygtk2reference/class-</a><br>
<div class="im">> gobjectmainloop.html, it seems that we must be able to add event<br>
> sources to gobject.mainloop<br>
<br>
</div>Yes. For instance, gobject.timeout_add(), gobject.idle_add() and<br>
gobject.io_add_watch() all add event sources to the default main context.<br>
<br>
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) tells dbus-python<br>
that when it needs to add an event source to "the" main loop, it should<br>
use equivalent C functions in GLib to do so.<br>
<br>
(In principle, DBusGMainLoop ought to take a GObject.MainContext as an<br>
optional argument - but that's never been implemented, and it currently<br>
always uses the default main context, which is the same one Gtk uses,<br>
and which should only be iterated from the main thread.)<br>
<div class="im"><br>
> Once the event sources are added, each instance of gobject.mainloop<br>
> (in its particular thread), will cater to only those sources.<br>
<br>
</div>No, that's not true; gobject.mainloop is a namespace for a set of global<br>
functions, not an object. If you must use multiple threads (not<br>
recommended), please see the GLib C API documentation for details of how<br>
main loops and main contexts relate, then the PyGtk documentation to see<br>
how that translates into Python.<br>
<div class="im"><br>
> How is dbus."mainloop.glib.DBusGMainLoop(set_as_default=True)"<br>
> related to gobject.mainloop?<br>
<br>
</div>It instantiates a new DBusGMainLoop and sets it as dbus-python's global<br>
default main-loop-integration object. (With hindsight, DBusGMainLoop was<br>
a poor choice of name - it should have been DBusGMainIntegration or<br>
something.) The result is that whenever a new dbus.connection.Connection<br>
is instantiated, it will call methods on that DBusGMainLoop to connect<br>
its event sources up to the default GLib main context, which is the same<br>
one used by Gtk.<br>
<br>
dbus.bus.BusConnection, dbus.Bus, dbus.SessionBus etc. are<br>
dbus.connection.Connection subclasses, so anything I say about<br>
dbus.connection.Connection applies equally to them.<br>
<div class="im"><br>
> How is dbus."mainloop.glib.DBusGMainLoop(set_as_default=False)"<br>
> related to gobject.mainloop?<br>
<br>
</div>It instantiates a new DBusGMainLoop and doesn't use it for anything. If<br>
you save the returned DBusGMainLoop in a variable (e.g.<br>
my_dbus_g_main_loop = DBusGMainLoop(...)), then you can pass a keyword<br>
argument mainloop=my_dbus_g_main_loop to a dbus.connection.Connection<br>
constructor, and that dbus.connection.Connection will use that<br>
DBusGMainLoop instead of dbus-python's global default. In practice, only<br>
a very unusual application would need to do that.<br>
<br>
There is currently no point in having more than one DBusGMainLoop; it<br>
would become useful if dbus-glib was thread-safe, and if dbus-python<br>
supported non-default GLib main-contexts.<br>
<div class="im"><br>
> Is it necessary at all to specify<br>
> "mainloop.glib.DBusGMainLoop(set_as_default=True)" or<br>
> "mainloop.glib.DBusGMainLoop(set_as_default=False)" when using<br>
> gobject.mainloop?<br>
<br>
</div>Yes. Otherwise, dbus-python has no way to know that your application is<br>
going to be iterating the GLib main loop, as opposed to Qt or Tk or<br>
Enlightenment or something.<br>
<div class="im"><br>
> currently for the client, I am having the (client) (parent) process<br>
> run the command "dbus-send" via the python-subprocess API.<br>
> Does there exist a python API to do it in a cleaner manner?<br>
<br>
</div>Yes, either dbus-python or GDBus. Each of those can do everything<br>
dbus-send can, and more.<br></blockquote><div><br>For a start, could you please point me to the paradigm to send a dbus-signal from the client to the server (where the server has the "add_to_signal_receiver" been set up).<br>
<br>From the limited googling that I did, I remember someone saying that for sending a signal, the typical setting-up-of-a-proxy-object is not required; however, I could not hit upon the exact dbus-python mechanism to send a signal :-\<br>
<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
S<br>
_______________________________________________<br>
dbus mailing list<br>
<a href="mailto:dbus@lists.freedesktop.org">dbus@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/dbus" target="_blank">http://lists.freedesktop.org/mailman/listinfo/dbus</a><br>
</blockquote></div><br><br clear="all"><br>-- <br>Regards,<br>Ajay<br>