Skip to content

Instantly share code, notes, and snippets.

@lf-
Created June 24, 2017 05:30
Show Gist options
  • Save lf-/8d6fb59651e132fe8fb9bdeadd23c3fd to your computer and use it in GitHub Desktop.
Save lf-/8d6fb59651e132fe8fb9bdeadd23c3fd to your computer and use it in GitHub Desktop.
A hack to get async dbus working (ironically it works with dbus-python, but not pydbus)
# <hack>
# our D-Bus library is missing async :(
# source: https://github.com/LEW21/pydbus/issues/58
def _async_result_handler(obj, result, user_data):
"""Generic callback dispatcher called from glib loop when an async method
call has returned. This callback is set up by method dbus_async_call."""
(result_callback, error_callback, real_user_data) = user_data
try:
ret = obj.call_finish(result)
except Exception:
etype, e = sys.exc_info()[:2]
# return exception as value
if error_callback:
error_callback(obj, e, real_user_data)
else:
result_callback(obj, e, real_user_data)
return
ret = ret.unpack()
# to be compatible with standard Python behaviour, unbox
# single-element tuples and return None for empty result tuples
if len(ret) == 1:
ret = ret[0]
elif len(ret) == 0:
ret = None
result_callback(obj, ret, real_user_data)
def dbus_async_call(proxymethod, instance, *args, timeout=30,
result_handler=None, error_handler=None, data=None):
"""
Call a D-Bus method asynchronously
Parameters:
proxymethod -- callable on the instance to call
instance -- dbus object to call a method on
timeout -- number of seconds before giving up
result_handler -- callback with signature (obj, result, data)
error_handler -- callback on error with signature (obj, err, data)
data -- arbitrary data that will be passed back with the handlers
"""
argdiff = len(args) - len(proxymethod._inargs)
if argdiff < 0:
raise TypeError(proxymethod.__qualname__ + ' missing {} required ' \
'positional argument(s)'.format(-argdiff))
elif argdiff > 0:
raise TypeError(proxymethod.__qualname__ + ' takes {} positional ' \
'argument(s) but {} was/were given'.format( \
len(proxymethod._inargs), len(args)))
timeout = timeout * 1000
user_data = (result_handler, error_handler, data)
ret = instance._bus.con.call(
instance._bus_name, instance._path,
proxymethod._iface_name, proxymethod.__name__,
GLib.Variant(proxymethod._sinargs, args),
GLib.VariantType.new(proxymethod._soutargs),
0, timeout, None,
_async_result_handler, user_data)
# </hack>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment