Detectin mainloop integration
Alexander Larsson
alexl at redhat.com
Thu Sep 27 07:31:48 PDT 2007
On Thu, 2007-09-27 at 15:32 +0200, Sebastian Dröge wrote:
> I've already added such function locally. Also a function for checking
> if the connection/server is integrated into a glib mainloop was added,
> this is needed as the connection_slot variable is used in dbus-glib
> in another place too (an assertion for checking if the connection is
> integrated with a main loop).
>
> Currently I have:
>
> void dbus_g_main_connection_setup (connection, context)
> void dbus_g_main_server_setup (connection, context)
>
> gboolean dbus_g_main_connection_is_setup (connection)
> gboolean dbus_g_main_server_is_setup (connection)
>
> void dbus_g_main_connection_unsetup (connection)
> void dbus_g_main_server_unsetup (server)
>
>
> The naming is of course not nice yet, suggestions welcome :)
> Maybe this should be renamed to:
>
> _set_context
> _has_context
> _unset_context
>
> or the other way around:
>
> dbus_g_main_integrate_
> dbus_g_main_unintegrate_
> dbus_g_main_*_is_integrated
>
> What do you think?
I'd like the integrate versions. Since thats what it does. It integrates
two different systems.
> > I think the problem I had was that dbus_connection_setup_with_g_main
> > owns the main context. Say you're using a custom mainloop + context pn a
> > thread, and then you do an async gio call on this thread, with this
> > mainloop. gvfs will then create a new peer-to-peer connection to the
> > gvfs daemon, and integrate this connection with the supplied main
> > context. However, when this thread later quits and unrefs of its main
> > context the dbus connection ows a ref to it, so its leaked, and the
> > connection isn't freed. What I wanted was that when the main context
> > goes away the dbus connection is un-integrated and we can free it.
>
> Owns? Well, it refs the main context and unrefs it when the connection
> is destroyed (by connection_setup_free).
Well, refs.
> What's exactly the problem with your example? The thread will quit and
> stop his main loop (which was integrated to the connection). When the
> connection later is destroyed the main loop will also be unreffed.
>
> Ok, now I see the problem, the main loops will only be freed when the
> connection is destroyed and thus we could have many unused main loops in
> memory.
>
> A way around this would of course be the function to unintegrate the
> main loop in the connection.
Thats not not whole problem though. There is no point where we're "done"
with the connection. Its stored until that mainloop goes away. However,
as the connection refs the mainloop it never goes away.
> > I don't think it ever really makes sense to integrate the shared session
> > bus with anything but the default main context, and then both objects
> > live forever, so that case is not very interesting.
>
> It's only possible to set one main loop for each connection. Having the
> shared session bus integrated in something else than the default main
> loop calls for trouble. Would it make sense to allow setting several
> main loops for each connection? I can't think of a useful use case ATM.
No, thats just pain.
> > So, we have left
> > three cases:
> > 1) Private connection integrated with default mainloop
> > 2) Private connection integrated with a custom mainloop
> > a) We control the custom mainloop
> > b) The custom mainloop was supplied from outside
> >
> > (case 2b is the gvfs case)
> >
> > I see three possible ownership solutions:
> > A) The integrated connection owns the mainloop
> > B) The mainloop owns the integrated connection
> > C) No ownership, both refs are weak
>
> How do you want to implement B)? There's nothing like a destroy notify
> for GMainContext unfortunately and I see no other way of unreffing the
> connection while the GMainContext disappears. So we only have A) und C)
> left IMHO.
When the GMainContext is unref:ed it destroys all the sources attached
to it. This will unref any callbacks in the source, and the destroy
notify for it (passed to g_source_set_callback) will be called.
> Also when choosing B) it would be weird that a connection can only have
> one main context but a main loop can have many connections.
How is this weird? You can only add a connection to one context, because
otherwise multiple threads would dispatch from the same connection which
is totally crazy. However, there is nothing weird with having multiple
conntections (maybe even to different endpoints) being dispatched to the
same thread. (In fact, thats the normal case.)
> > This means the code has to be restructured a bit though. The gvfs code
> > actually uses solution C atm, which is not ideal. However, it is
> > probably a better base for an implementation of solution B.
>
> So what are exactly the properties you want to have?
> You definitely want that the connection is alive exactly until the main
> loop is stopped, so the main loop somehow has to own a reference on
> the connection and we need some way to unref the connection when
> the main loop quits.
Yes. See above.
> Do you also want to have a connection serving more than one main loop?
It would be more like "a connection served by more than one main loop",
and this is not wanted. The messages would be dispatched to random
mainloops (and thus threads), different for each message. I'm pretty
sure nothing will need this, as its totally unpredictable.
More information about the dbus
mailing list