emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Automatic value conversion in DBus bindings


From: Jan Moringen
Subject: Re: Automatic value conversion in DBus bindings
Date: Mon, 27 Jul 2009 07:49:50 +0200

Hi Michael.

Thank you for the quick reply. Maybe I wasn't clear enough about this in
my first message. I think there are two separate problems. 

I tried to demonstrate the first with the code below.

> > While playing around with the DBus bindings, I came across some problems
> > related to the automatic conversion between LISP and DBus values.
> >
> > The first problem can be demonstrated by running the following code:
> >
> >   (require 'dbus)
> >
> >   (defun test ()
> >     nil)
> >
> >   (dbus-register-method
> >    :session "org.gnu.emacs" "/org/gnu/emacs" "org.gnu.Emacs" "test"
> >    #'test)
> >
> >   (dbus-call-method-non-blocking
> >    :session "org.gnu.emacs" "/org/gnu/emacs" "org.gnu.Emacs" "test")
> 
> If you don't want to get a return value, you shall call
> 
> (dbus-call-method-asynchronously
>  :session "org.gnu.emacs" "/org/gnu/emacs" "org.gnu.Emacs" "test" 'ignore)

In this case (the code above) the problem is not whether the caller
receives a return value or not, but whether the call returns at all. It
does return fine as long as `test' does not return nil. A value of nil
causes an infinite loop in `dbus-call-method-non-blocking' as I
explained:

> (while (not (gethash key dbus-return-values-table nil))
>     (read-event nil nil 0.1))
> 
> Here, the return value nil cannot be distinguished from "no return
> value
> yet".

The second problem is not being able to not return any values from a
DBus-invokable function.

> > The original motivation for my experiments was writing a function that
> > should receive DBus calls but not return a value. This was necessary
> > since another process (Empathy) would call the method via DBus and
> > complain if it returned anything.
> 
> How is your function called from Empathy? If it is
> dbus_connection_send_with_reply_and_block or
> dbus_connection_send_with_reply, you *must* return a value. In the case
> of dbus_connection_send (that's what I suspect) it doesn't matter, I believe.

I think that a *reply* is required, too. The problem seems to be, that
it must not have *return values* in it. I could not find the call in the
Empathy source (they seem to use gobject DBus proxies and other stuff
that I am not familiar with), but I recorded two dumps with
dbus-monitor, that hopefully illustrate the problem.

The general setup is as follows: The Emacs process takes the bus name
org.gnome.Empathy.StreamTubeHandler.x_rudel_infinote and registers an
object /org/gnome/Empathy/StreamTubeHandler/x_rudel_infinote with a
method org.gnome.Empathy.TubeHandler.HandleTube. This method is invoked
by Empathy.

The following dump shows a successful attempt in which the Emacs process
sent a method return message that does not include any return values. I
produced this with the patch from my first message applied.
----------------------------------------------------------------------
method call
  sender=:1.0 -> dest=org.gnome.Empathy.StreamTubeHandler.x_rudel_infinote 
  serial=112
  path=/org/gnome/Empathy/StreamTubeHandler/x_rudel_infinote; 
  interface=org.gnome.Empathy.TubeHandler; 
  member=HandleTube
    string ":1.4"
    object path 
"/org/freedesktop/Telepathy/Connection/gabble/jabber/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    object path 
"/org/freedesktop/Telepathy/Connection/gabble/jabber/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/StreamTubeChannel_2_1647872899"
    uint32 1
    uint32 2
method return 
  sender=:1.10 -> dest=:1.0 
  reply_serial=112
----------------------------------------------------------------------

The following dump show an unsuccessful attempt. The method call is
identical but this time the patch wasn't in place and thus the function
in the Emacs process was forced to return a value. I arbitrarily decided
to return 1. This return value is sent to Empathy as the method return
message indicates. However Empathy seems to insist on a method return
message that has no return values in it (see below).
----------------------------------------------------------------------
method call 
  sender=:1.0 -> dest=org.gnome.Empathy.StreamTubeHandler.x_rudel_infinote 
  serial=124 
  path=/org/gnome/Empathy/StreamTubeHandler/x_rudel_infinote; 
  interface=org.gnome.Empathy.TubeHandler; 
  member=HandleTube
    string ":1.4"
    object path 
"/org/freedesktop/Telepathy/Connection/gabble/jabber/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    object path 
"/org/freedesktop/Telepathy/Connection/gabble/jabber/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/StreamTubeChannel_2_459526684"
    uint32 1
    uint32 2
method return
  sender=:1.10 -> dest=:1.0
  reply_serial=124
    uint32 1
----------------------------------------------------------------------
This is the error message Empathy produces when it receives the method
return message with the return value in it:
----------------------------------------------------------------------
Unable to start application for service x_rudel_infinote: Too many
arguments in reply; expected 0, got 1
----------------------------------------------------------------------

I have no idea how I could work around this problem without the ability
to not return any values from a DBus-invoked function. If further
explanations or tests are required, I would be happy to provide them.

Thanks in advance.

Kind regards,
Jan





reply via email to

[Prev in Thread] Current Thread [Next in Thread]