5 from gi.repository import GObject
7 from .common import ST_ACTIVE, ST_TRANSITION, OnoffDevice
8 from .gobject import spawn_child
10 logger = logging.getLogger("onoff.process")
12 class OnoffProcess(OnoffDevice):
13 def __init__(self, command, start_wait=0, termsig=signal.SIGTERM):
14 OnoffDevice.__init__(self)
15 self.command = command
16 self.start_wait = start_wait
17 self.termsig = termsig
18 self.desired_state = 0 # bit mask of just ST_ACTIVE
20 self.starting = None # timeout event during start
21 self.watch = None # watch event
26 if self.starting or self.killed:
27 return self.desired_state | ST_TRANSITION
28 return self.desired_state
30 def start_process(self):
31 assert self.pid is None
32 assert self.starting is None
33 logger.info("starting command %s", " ".join(self.command))
34 self.pid, self.watch = spawn_child(self.command, self.process_died)
35 logger.debug("started as pid %d", self.pid)
36 self.starting = GObject.timeout_add(1000 * self.start_wait,
38 self.changestate(self.state)
40 def cancel_start_wait(self):
41 if self.starting is None:
43 logger.debug("cancelling start notification")
44 ret = GObject.source_remove(self.starting)
48 def process_died(self, pid, condition):
49 assert self.pid == pid
50 assert self.watch is not None
54 logger.info("process %d died", pid)
55 self.cancel_start_wait()
56 if self.desired_state == ST_ACTIVE:
59 self.changestate(self.state)
61 def process_started(self):
62 assert self.desired_state == ST_ACTIVE
63 assert self.starting is not None
65 logger.debug("process started")
66 self.changestate(self.state)
68 def stop_process(self):
69 assert self.pid is not None
70 assert self.watch is not None
71 self.cancel_start_wait()
72 logger.info("killing process %d", self.pid)
73 os.kill(self.pid, self.termsig)
75 self.changestate(self.state)
78 if self.desired_state != ST_ACTIVE:
79 self.desired_state = ST_ACTIVE
83 logger.debug("already activated. nothing to do")
86 if self.desired_state != 0:
87 self.desired_state = 0
88 if self.pid is not None and not self.killed:
91 logger.debug("already deactivated. nothing to do.")