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