change activatefd signature
authorHelmut Grohne <helmut@subdivi.de>
Mon, 17 Jun 2013 18:15:59 +0000 (20:15 +0200)
committerHelmut Grohne <helmut@subdivi.de>
Mon, 17 Jun 2013 18:18:14 +0000 (20:18 +0200)
The method no longer takes a UnixFd, but returns one. This is copied
from the systemd inhibitor interface. Advantages:

 * Not having fds to arbitrary things in the service is probably a good
   thing.
 * Maybe the interfaces can converge?

dbus_client.py
dbus_service.py

index 31c0594..691d86b 100755 (executable)
@@ -1,7 +1,6 @@
 #!/usr/bin/env python
 
 import os
-import socket
 import sys
 
 import dbus
@@ -21,15 +20,14 @@ def wait_for_signal(proxy, signal):
     return state[0]
 
 def main():
-    s1, s2 = socket.socketpair()
     DBusGMainLoop(set_as_default=True)
     bus = dbus.SessionBus()
     proxy = bus.get_object("de.subdivi.onoff0", "/de/subdivi/onoff0/redshift")
     if len(sys.argv) > 1:
-        st = proxy.activatefd(dbus.types.UnixFd(s1), 10)
-        s1.close()
-        os.dup2(s2.fileno(), 254)
-        s2.close()
+        st, fd = proxy.activatefd(10)
+        fd = fd.take()
+        os.dup2(fd, 254)
+        os.close(fd)
         if st != ST_ACTIVE:
             print("state is %d waiting for signal" % st)
             st = wait_for_signal(proxy, "changestate")
index 01f4966..89acc3a 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 import logging
-import os
+import socket
 
 import dbus
 import dbus.service
@@ -13,6 +13,15 @@ import onoff.process
 
 logger = logging.getLogger("dbus_service")
 
+def dbus_socket_pair():
+    """Create a socket pair where the latter end is suitable for dbus.
+    @rtype: (socket, dbus.types.UnixFd)
+    """
+    s1, s2 = socket.socketpair()
+    s3 = dbus.types.UnixFd(s2)
+    s2.close()
+    return s1, s3
+
 class OnoffControl(dbus.service.Object):
     domain = "de.subdivi.onoff0"
     path = "/de/subdivi/onoff0"
@@ -38,17 +47,17 @@ class OnoffControl(dbus.service.Object):
         GObject.timeout_add(duration * 1000, self.unuse)
         return self.use()
 
-    @dbus.service.method(domain, in_signature="hq", out_signature="q")
-    def activatefd(self, fd, duration):
-        fd = fd.take()
-        logger.info("activatefd fd %d, duration %d", fd, duration)
+    @dbus.service.method(domain, in_signature="q", out_signature="qh")
+    def activatefd(self, duration):
+        logger.info("activatefd duration %d", duration)
+        notifyfd, retfd = dbus_socket_pair()
         def callback(fd, _):
-            logger.info("fd %d completed", fd)
-            os.close(fd)
+            logger.info("fd %d completed", fd.fileno())
+            fd.close()
             GObject.timeout_add(duration * 1000, self.unuse)
             return False
-        GObject.io_add_watch(fd, GObject.IO_HUP|GObject.IO_ERR, callback)
-        return self.use()
+        GObject.io_add_watch(notifyfd, GObject.IO_HUP|GObject.IO_ERR, callback)
+        return (self.use(), retfd)
 
     def use(self):
         self.usecount += 1