blob: c5cb9a8780e928a6c23ecea0e87329125f59489c [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001From 39a7d79ee6c548902fbac8b95c934af7e4c69260 Mon Sep 17 00:00:00 2001
2From: Vendula Poncova <vponcova@redhat.com>
3Date: Thu, 2 Aug 2018 15:30:45 +0800
4Subject: [PATCH 1/2] Support asynchronous calls (#58)
5
6Added support for asynchronous calls of methods. A method is called
7synchronously unless its callback parameter is specified. A callback
8is a function f(*args, returned=None, error=None), where args is
9callback_args specified in the method call, returned is a return
10value of the method and error is an exception raised by the method.
11
12Example of an asynchronous call:
13
14def func(x, y, returned=None, error=None):
15 pass
16
17proxy.Method(a, b, callback=func, callback_args=(x, y))
18
19Upstream-Status: Cherry-pick [https://src.fedoraproject.org/cgit/rpms/python-pydbus.git/]
20
21Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
22---
23 pydbus/proxy_method.py | 44 ++++++++++++++++++++++++++++++++++++++------
24 1 file changed, 38 insertions(+), 6 deletions(-)
25
26diff --git a/pydbus/proxy_method.py b/pydbus/proxy_method.py
27index 8798edd..4ea4304 100644
28--- a/pydbus/proxy_method.py
29+++ b/pydbus/proxy_method.py
30@@ -65,15 +65,34 @@ class ProxyMethod(object):
31
32 # Python 2 sux
33 for kwarg in kwargs:
34- if kwarg not in ("timeout",):
35+ if kwarg not in ("timeout", "callback", "callback_args"):
36 raise TypeError(self.__qualname__ + " got an unexpected keyword argument '{}'".format(kwarg))
37 timeout = kwargs.get("timeout", None)
38+ callback = kwargs.get("callback", None)
39+ callback_args = kwargs.get("callback_args", tuple())
40+
41+ call_args = (
42+ instance._bus_name,
43+ instance._path,
44+ self._iface_name,
45+ self.__name__,
46+ GLib.Variant(self._sinargs, args),
47+ GLib.VariantType.new(self._soutargs),
48+ 0,
49+ timeout_to_glib(timeout),
50+ None
51+ )
52+
53+ if callback:
54+ call_args += (self._finish_async_call, (callback, callback_args))
55+ instance._bus.con.call(*call_args)
56+ return None
57+ else:
58+ ret = instance._bus.con.call_sync(*call_args)
59+ return self._unpack_return(ret)
60
61- ret = instance._bus.con.call_sync(
62- instance._bus_name, instance._path,
63- self._iface_name, self.__name__, GLib.Variant(self._sinargs, args), GLib.VariantType.new(self._soutargs),
64- 0, timeout_to_glib(timeout), None).unpack()
65-
66+ def _unpack_return(self, values):
67+ ret = values.unpack()
68 if len(self._outargs) == 0:
69 return None
70 elif len(self._outargs) == 1:
71@@ -81,6 +100,19 @@ class ProxyMethod(object):
72 else:
73 return ret
74
75+ def _finish_async_call(self, source, result, user_data):
76+ error = None
77+ return_args = None
78+
79+ try:
80+ ret = source.call_finish(result)
81+ return_args = self._unpack_return(ret)
82+ except Exception as err:
83+ error = err
84+
85+ callback, callback_args = user_data
86+ callback(*callback_args, returned=return_args, error=error)
87+
88 def __get__(self, instance, owner):
89 if instance is None:
90 return self
91--
922.7.4
93