use the enum module to represent states
[~helmut/onoff.git] / onoff / process.py
index 2b75bda..6d738c7 100644 (file)
@@ -2,9 +2,7 @@ import logging
 import os
 import signal
 
-from gi.repository import GObject
-
-from .common import ST_ACTIVE, ST_TRANSITION, OnoffDevice
+from .common import OnoffDevice, OnoffState
 from .gobject import spawn_child
 
 logger = logging.getLogger("onoff.process")
@@ -16,101 +14,69 @@ class OnoffProcess(OnoffDevice):
     @type pid: int or None
     @ivar pid: is either None if there is no process or the pid of the
             spawned process
-    @ivar starting: is either None or a GObject event source id of the
-            callback sigalling the end of the activation transition.
-    @ivar watch: is either None or a GObject event source id of the
-            callback waiting for the termination of the spawned process.
+    @ivar starting: is either None or a ScheduledFunction representing the
+            callback signalling the end of the activation transition.
     @type killed: bool
     @ivar killed: indicates whether the termination signal has been sent
             to the spawned process.
     """
-    def __init__(self, command, start_wait=0, termsig=signal.SIGTERM):
+    def __init__(self, command, termsig=signal.SIGTERM):
         """
         @type command: [str]
         @param command: an argument vector to be executed. The first element
                 is used as executable and looked up in $PATH.
-        @param start_wait: duration of the transition period from inactive to
-                active in seconds.
         @param termsig: termination signal to be sent to the process to
                 deactivate it. The process must exit in response to this
                 signal.
         """
         OnoffDevice.__init__(self)
         self.command = command
-        self.start_wait = start_wait
         self.termsig = termsig
-        self.desired_state = 0 # bit mask of just ST_ACTIVE
+        self.desired_state = OnoffState.inactive
         self.pid = None
-        self.starting = None # timeout event during start
-        self.watch = None # watch event
         self.killed = False
 
     @property
     def state(self):
-        if self.starting or self.killed:
-            return self.desired_state | ST_TRANSITION
+        if self.killed:
+            return self.desired_state | OnoffState.transition
         return self.desired_state
 
     def start_process(self):
         assert self.pid is None
-        assert self.starting is None
         logger.info("starting command %s", " ".join(self.command))
-        self.pid, self.watch = spawn_child(self.command, self.process_died)
+        self.pid = spawn_child(self.command, self.process_died)
         logger.debug("started as pid %d", self.pid)
-        self.starting = GObject.timeout_add(int(1000 * self.start_wait),
-                                            self.process_started)
+        assert self.desired_state == OnoffState.active
+        logger.debug("process started")
         self.changestate(self.state)
 
-    def cancel_start_wait(self):
-        if self.starting is None:
-            return
-        logger.debug("cancelling start notification")
-        ret = GObject.source_remove(self.starting)
-        assert ret
-        self.starting = None
-
     def process_died(self, pid, condition):
         assert self.pid == pid
-        assert self.watch is not None
-        self.watch = None
         self.pid = None
         self.killed = False
         logger.info("process %d died", pid)
-        self.cancel_start_wait()
-        if self.desired_state == ST_ACTIVE:
+        if self.desired_state == OnoffState.active:
             self.start_process()
         else:
             self.changestate(self.state)
 
-    def process_started(self):
-        assert self.desired_state == ST_ACTIVE
-        assert self.starting is not None
-        self.starting = None
-        logger.debug("process started")
-        self.changestate(self.state)
-
-    def stop_process(self):
-        assert self.pid is not None
-        assert self.watch is not None
-        self.cancel_start_wait()
-        logger.info("killing process %d", self.pid)
-        os.kill(self.pid, self.termsig)
-        self.killed = True
-        self.changestate(self.state)
-
     def activate(self):
-        if self.desired_state != ST_ACTIVE:
-            self.desired_state = ST_ACTIVE
+        if self.desired_state != OnoffState.active:
+            self.desired_state = OnoffState.active
             if self.pid is None:
                 self.start_process()
             else:
                 logger.debug("already activated. nothing to do")
 
     def deactivate(self):
-        if self.desired_state != 0:
-            self.desired_state = 0
+        if self.desired_state != OnoffState.inactive:
+            self.desired_state = OnoffState.inactive
             if self.pid is not None and not self.killed:
-                self.stop_process()
+                logger.info("killing process %d", self.pid)
+                os.kill(self.pid, self.termsig)
+                self.killed = True
+                self.changestate(self.state)
             else:
                 logger.debug("already deactivated. nothing to do.")