Re: GVariant support for Unix fds (Was Re: GDBus/GVariant plans for next GLib release)
- From: David Zeuthen <david fubar dk>
- To: Ryan Lortie <desrt desrt ca>
- Cc: gtk-devel-list gnome org
- Subject: Re: GVariant support for Unix fds (Was Re: GDBus/GVariant plans for next GLib release)
- Date: Mon, 09 Nov 2009 08:21:55 -0500
Hey Ryan,
Sorry for the lag,
On Sat, 2009-10-31 at 17:27 -0400, Ryan Lortie wrote:
> On Tue, 2009-10-20 at 11:17 -0400, David Zeuthen wrote:
> > So how about something like 1. and 2. below? We'd put
> >
> > g_dbus_connection_get_handle_for_unix_fd()
> > g_dbus_connection_set_handle_for_unix_fd()
>
> I was actually thinking that we could introduce a GDBusFDSet:
>
> gint g_dbus_fd_set_add_fd (gint fd) {
> list_of_fds[fd_count] = dup (fd);
> return fd_count++;
> }
>
> gint g_dbus_fd_set_get_fd (gint index) {
> return dup (list_of_fds[index]);
> }
>
> g_dbus_fd_set_finalize () {
> foreach (fd in list_of_fds) close (fd);
> }
>
> You'd add fds to that and get ints back (starting at 0 per the set).
> Then when sending the dbus message you'd give the GVariant and the
> DBusFDSet to the appropriate function.
>
> var fd = open("file");
> var fdset = new FDSet ();
> var message = new GVariant ("(sh)",
> "hello world",
> fdset.add_fd (fd));
>
> g_dbus_proxy_invoke_with_fds (proxy, "Foo", message, fdset, ...);
>
> When receiving messages, you get a DBusFDSet handed to you in the event
> that there were file descriptors (or just %NULL in case not).
>
> The fds held in the GDBusFDSet are closed when the set is finalized.
> There is no doubt about who owns which fd in this case -- and in the
> case you elect to ignore fds that were sent to you then everything is
> still cleaned up properly.
Hmm, I don't like this approach. It means you'd have to pass this
GDBusFDSet object around in code you use to build/parse the GVariant. In
particular, your proposed GTypeSerializer would need support for it.
That's problematic because that one lives in libgobject, not libgio
(where GDBusFDSet would live).
I still think the approach I described works better.
For example, suppose I have a C type mapping that maps a{sh} to a
GHashTable from strings to gint. I'd like to write code like this
my_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (my_hash,
"fd-for-client",
GINT_TO_POINTER (fd_for_client));
/* need to keep fd_for_client alive until we hand off the hash */
<other code>
foo_bar_invoke_process_client (proxy, my_hash, <async stuff>);
g_hash_table_unref (my_hash);
/* it's now safe to close the fd, the dbus stuff has already dupped
* it... note that we could have just used a GDestroyNotify for the
* values in my_hash to do this.
*/
close (fd_for_client);
where the latter function represents a generated function for the
ProcessClient() method on the foo.Bar interface that takes a single
a{sh} parameter represented by a GHashTable.
On the receiving end it would look like this. Suppose the GimmeFds
function returns a a{sh}:
my_hash = foo_bar_invoke_gimme_fds_sync (proxy, cancelable, &error);
fd = GPOINTER_TO_INT (g_hash_table_lookup (my_hash, "stream1"));
if (fd > 0)
{
fd_for_stream1 = dup (fd);
}
/* the value destroy notifier on my_hash closes all fds */
g_hash_table_unref (my_hash);
<now use fd_for_stream1 and close it when done>
Thoughts?
Thanks,
David
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]