From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Jan Moringen Newsgroups: gmane.emacs.devel Subject: DBus methods without name grabbing Date: Sun, 02 Jan 2011 22:06:04 +0100 Message-ID: <19384_1294002375_ZZh0g13mCbLkV.00_1294002364.12635.44.camel@gunhead> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_2leOPa4DZocptkbHN+xBOw)" X-Trace: dough.gmane.org 1294003609 32255 80.91.229.12 (2 Jan 2011 21:26:49 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 2 Jan 2011 21:26:49 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jan 02 22:26:44 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PZVRq-00043e-3r for ged-emacs-devel@m.gmane.org; Sun, 02 Jan 2011 22:26:42 +0100 Original-Received: from localhost ([127.0.0.1]:56219 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PZVHM-0008MI-JG for ged-emacs-devel@m.gmane.org; Sun, 02 Jan 2011 16:15:52 -0500 Original-Received: from [140.186.70.92] (port=35669 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PZV8W-00015j-Pp for emacs-devel@gnu.org; Sun, 02 Jan 2011 16:07:01 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PZV86-0001gz-60 for emacs-devel@gnu.org; Sun, 02 Jan 2011 16:06:44 -0500 Original-Received: from mux2-unibi-smtp.hrz.uni-bielefeld.de ([129.70.204.73]:47668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PZV85-0001fY-Nc for emacs-devel@gnu.org; Sun, 02 Jan 2011 16:06:18 -0500 Original-Received: from pmxchannel-daemon.mux2-unibi-smtp.hrz.uni-bielefeld.de by mux2-unibi-smtp.hrz.uni-bielefeld.de (Sun Java(tm) System Messaging Server 6.3-6.03 (built Mar 14 2008; 32bit)) id <0LEE00200YMFQC00@mux2-unibi-smtp.hrz.uni-bielefeld.de> for emacs-devel@gnu.org; Sun, 02 Jan 2011 22:06:15 +0100 (CET) Original-Received: from [192.168.2.102] ([217.25.168.153]) by mux2-unibi-smtp.hrz.uni-bielefeld.de (Sun Java(tm) System Messaging Server 6.3-6.03 (built Mar 14 2008; 32bit)) with ESMTPPSA id <0LEE003DVYMDTIB0@mux2-unibi-smtp.hrz.uni-bielefeld.de> for emacs-devel@gnu.org; Sun, 02 Jan 2011 22:06:14 +0100 (CET) X-Mailer: Evolution 2.30.3 X-EnvFrom: jan.moringen@uni-bielefeld.de X-PMX-Version: 5.5.9.395186, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2011.1.2.210017, pmx10 X-Connecting-IP: 217.25.168.153 X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:134173 Archived-At: --Boundary_(ID_2leOPa4DZocptkbHN+xBOw) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Hi, recently I ran into the following DBus-related problem: In order to write a telepathy client [1], it is required to provide a certain DBus-Interface under a special well-known name. Some telepathy component seems to start calling methods immediately after the well-known name is taken. Since the interface consists of multiple methods/properties, it cannot be ensured that the interface is completely available when the name is taken and the first calls are made using Emacs' current DBus-interface. This is due to the fact that the function `dbus-register-method' immediately takes the name. To allow Emacs to work with this kind of DBus-interfaces, I suggest the changes implemented in the attached patch. I don't known the Emacs C code well very well, so it probably needs revision. An example for which this change is necessary can be found in the function `telepathy-client-register' in the attached file client.el from my telepathy bindings. Do you think this patch could be applied? Kind regards, Jan [1] http://telepathy.freedesktop.org/spec/Client.html --Boundary_(ID_2leOPa4DZocptkbHN+xBOw) Content-type: text/x-patch; name=dbus-dont-request-name.diff; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=dbus-dont-request-name.diff === modified file 'lisp/net/dbus.el' --- lisp/net/dbus.el 2010-08-30 13:03:05 +0000 +++ lisp/net/dbus.el 2010-10-03 02:25:51 +0000 @@ -868,7 +868,8 @@ (add-to-list 'result (cons (car dict) (caadr dict)) 'append))))) (defun dbus-register-property - (bus service path interface property access value &optional emits-signal) + (bus service path interface property access value + &optional emits-signal dont-request-name) "Register property PROPERTY on the D-Bus BUS. BUS is either a Lisp symbol, `:system' or `:session', or a string @@ -899,7 +900,8 @@ (signal 'dbus-error (list "Access type invalid" access))) ;; Register SERVICE. - (unless (member service (dbus-list-names bus)) + (unless (or dont-request-name + (member service (dbus-list-names bus))) (dbus-call-method bus dbus-service-dbus dbus-path-dbus dbus-interface-dbus "RequestName" service 0)) @@ -907,11 +909,14 @@ ;; Add the handler. We use `dbus-service-emacs' as service name, in ;; order to let unregister SERVICE despite of this default handler. (dbus-register-method - bus service path dbus-interface-properties "Get" 'dbus-property-handler) + bus service path dbus-interface-properties "Get" 'dbus-property-handler + dont-request-name) (dbus-register-method - bus service path dbus-interface-properties "GetAll" 'dbus-property-handler) + bus service path dbus-interface-properties "GetAll" 'dbus-property-handler + dont-request-name) (dbus-register-method - bus service path dbus-interface-properties "Set" 'dbus-property-handler) + bus service path dbus-interface-properties "Set" 'dbus-property-handler + dont-request-name) ;; Send the PropertiesChanged signal. (when emits-signal === modified file 'src/dbusbind.c' --- src/dbusbind.c 2010-10-01 13:56:33 +0000 +++ src/dbusbind.c 2010-10-03 02:17:34 +0000 @@ -1947,7 +1947,7 @@ } DEFUN ("dbus-register-method", Fdbus_register_method, Sdbus_register_method, - 6, 6, 0, + 6, 7, 0, doc: /* Register for method METHOD on the D-Bus BUS. BUS is either a Lisp symbol, `:system' or `:session', or a string @@ -1961,7 +1961,7 @@ Lisp function to be called when a method call is received. It must accept the input arguments of METHOD. The return value of HANDLER is used for composing the returning D-Bus message. */) - (Lisp_Object bus, Lisp_Object service, Lisp_Object path, Lisp_Object interface, Lisp_Object method, Lisp_Object handler) + (Lisp_Object bus, Lisp_Object service, Lisp_Object path, Lisp_Object interface, Lisp_Object method, Lisp_Object handler, Lisp_Object dont_request_name) { Lisp_Object key, key1, value; DBusConnection *connection; @@ -1983,10 +1983,16 @@ /* Request the known name from the bus. We can ignore the result, it is set to -1 if there is an error - kind of redundancy. */ - dbus_error_init (&derror); - result = dbus_bus_request_name (connection, SDATA (service), 0, &derror); - if (dbus_error_is_set (&derror)) - XD_ERROR (derror); + if (!dont_request_name || NILP (dont_request_name)) + { + dbus_error_init (&derror); + result = dbus_bus_request_name (connection, SDATA (service), 0, &derror); + if (dbus_error_is_set (&derror)) + XD_ERROR (derror); + + /* Cleanup. */ + dbus_error_free (&derror); + } /* Create a hash table entry. We use nil for the unique name, because the method might be called from anybody. */ @@ -1997,9 +2003,6 @@ if (NILP (Fmember (key1, value))) Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table); - /* Cleanup. */ - dbus_error_free (&derror); - /* Return object. */ return list2 (key, list3 (service, path, handler)); } --Boundary_(ID_2leOPa4DZocptkbHN+xBOw) Content-type: text/x-emacs-lisp; name=client.el; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=client.el ;;; client.el --- ;; ;; Copyright (C) 2010, 2011 Jan Moringen ;; ;; Author: Jan Moringen ;; Keywords: telepathy, communication, instant messaging ;; ;; This Program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; ;; This Program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; ;;; History: ;; ;; 0.1 - Initial version ;;; Code: ;; (require 'dbus) (require 'telepathy/util) ;;; ;; (defconst telepathy-client-introspection-data " " "") ;;; ;; (defvar telepathy-client-handlers (make-hash-table :test 'equal) "") (defun telepathy-client-handler-services () "" (let ((result)) (maphash (lambda (key value) (push key result)) telepathy-client-handlers) result)) (defun telepathy-client-add-handler (service handler &optional client) "" (unless client (setq client "Emacs")) (unless (zerop (hash-table-count telepathy-client-handlers)) (telepathy-client-unregister client)) (puthash service handler telepathy-client-handlers) (telepathy-client-register client)) (defun telepathy-client-remove-handler (service &optional client) "" (unless client (setq client "Emacs")) (unless (zerop (hash-table-count telepathy-client-handlers)) (telepathy-client-unregister client)) (remhash service telepathy-client-handlers) (unless (zerop (hash-table-count telepathy-client-handlers)) (telepathy-client-register client))) ;;; ;; (defun telepath-client-channel-handler (account connection-path channels &rest args) "" (dolist (channel-data channels) (let* ((connection (telepathy-make-remote-proxy-from-path :session connection-path)) ;; Analyze the properties of the channel. (channel-properties (second channel-data)) (contact-handle (telepathy-prop-get telepathy-key-target-handle channel-properties)) (contact (telepathy-make-contact connection contact-handle)) (service (telepathy-prop-get telepathy-key-service channel-properties)) (handler (gethash service telepathy-client-handlers)) ;; Obtain object path of channel object. (channel-path (first channel-data)) (channel-service (let ((bla (telepathy-path->service channel-path))) (substring bla 0 (position ?. bla :from-end t)))) (channel-object (dbus-proxy-make-remote-proxy :session channel-service channel-path nil 'telepathy-tube))) ;; TODO could be a different kind of channel (oset channel-object :contact contact) (message "Channel") (message " Path %s" channel-path) (message " Service %s" service) (message " Contact %s" contact) (funcall handler channel-object))) :ignore) (defun telepathy-client-register (name) "" ;; Create a DBus object to handle tube requests. (let ((service (format "org.freedesktop.Telepathy.Client.%s" name)) (path (format "/org/freedesktop/Telepathy/Client/%s" name))) ;; Install introspection information. (lexical-let ((introspection-data (format telepathy-client-introspection-data name))) (dbus-register-method :session service path "org.freedesktop.DBus.Introspectable" "Introspect" (lambda (&rest args) introspection-data) t)) ;; don't request the name, yet ;; Register all properties belonging to the handler object. (dolist (name-and-value `(("HandlerChannelFilter" ,(mapcar #'telepathy-client-make-channel-filter (telepathy-client-handler-services))) ("BypassApproval" t) ;; TODO was nil ("Capabilities" (:array :signature "as")) ("HandledChannels" (:array :signature "ao")))) (destructuring-bind (name value) name-and-value (dbus-register-property :session service path "org.freedesktop.Telepathy.Client.Handler" name :read value nil t))) ;; don't request the name, yet ;; TODO store the dbus objects for unregistering? (dbus-register-method :session service path "org.freedesktop.Telepathy.Client.Handler" "HandleChannels" #'telepath-client-channel-handler t) ;; don't request the name, yet (dbus-register-property :session service path "org.freedesktop.Telepathy.Client" "Interfaces" :read '("org.freedesktop.Telepathy.Client.Handler") nil t) ;; don't request the name, yet ;; Now that everything is in place, request the name. (dbus-call-method :session dbus-service-dbus dbus-path-dbus dbus-interface-dbus "RequestName" service 0))) ;; (/org/freedesktop/Telepathy/Connection/gabble/jabber/scymtym_2dtest_40jabber_2eorg_2fbe153d1c/StreamTubeChannel_2_1273735221 ;; ((org.freedesktop.Telepathy.Channel.InitiatorID ;; (scymtym@jabber.org)) ;; (org.freedesktop.Telepathy.Channel.TargetHandleType ;; (1)) ;; (org.freedesktop.Telepathy.Channel.TargetHandle ;; (2)) ;; (org.freedesktop.Telepathy.Channel.TargetID ;; (scymtym@jabber.org)) ;; (org.freedesktop.Telepathy.Channel.Requested ;; (nil)) ;; (org.freedesktop.Telepathy.Channel.Type.StreamTube.SupportedSocketTypes ;; (((0 (0 3)) (2 (0 1)) (3 (0 1))))) ;; (org.freedesktop.Telepathy.Channel.Type.StreamTube.Service ;; (org.gnu.emacs.rudel.announce)) ;; (org.freedesktop.Telepathy.Channel.Interface.Tube.Parameters ;; (nil)) ;; (org.freedesktop.Telepathy.Channel.ChannelType ;; (org.freedesktop.Telepathy.Channel.Type.StreamTube)) ;; (org.freedesktop.Telepathy.Channel.InitiatorHandle ;; (2)) ;; (org.freedesktop.Telepathy.Channel.Interfaces ;; ((org.freedesktop.Telepathy.Channel.Interface.Tube))))) (defun telepathy-client-unregister (name) "" (dbus-unregister-service :session (format "org.freedesktop.Telepathy.Client.%s" name))) ;;; Helper functions ;; (defun telepathy-client-make-channel-filter (service) "" `((:dict-entry "org.freedesktop.Telepathy.Channel.ChannelType" (:variant :string "org.freedesktop.Telepathy.Channel.Type.StreamTube")) (:dict-entry "org.freedesktop.Telepathy.Channel.TargetHandleType" (:variant :uint32 1)) (:dict-entry "org.freedesktop.Telepathy.Channel.Requested" (:variant :boolean nil)) (:dict-entry "org.freedesktop.Telepathy.Channel.Type.StreamTube.Service" (:variant :string ,service)) )) (provide 'telepathy/client) ;;; client.el ends here --Boundary_(ID_2leOPa4DZocptkbHN+xBOw)--