Statistics
| Branch: | Tag: | Revision:

root / lib / daemon.py @ 8b3fd458

History | View | Annotate | Download (2.8 kB)

1 821d9e43 Michael Hanselmann
#
2 821d9e43 Michael Hanselmann
#
3 821d9e43 Michael Hanselmann
4 821d9e43 Michael Hanselmann
# Copyright (C) 2006, 2007, 2008 Google Inc.
5 821d9e43 Michael Hanselmann
#
6 821d9e43 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 821d9e43 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 821d9e43 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 821d9e43 Michael Hanselmann
# (at your option) any later version.
10 821d9e43 Michael Hanselmann
#
11 821d9e43 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 821d9e43 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 821d9e43 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 821d9e43 Michael Hanselmann
# General Public License for more details.
15 821d9e43 Michael Hanselmann
#
16 821d9e43 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 821d9e43 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 821d9e43 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 821d9e43 Michael Hanselmann
# 02110-1301, USA.
20 821d9e43 Michael Hanselmann
21 821d9e43 Michael Hanselmann
22 821d9e43 Michael Hanselmann
"""Module with helper classes and functions for daemons"""
23 821d9e43 Michael Hanselmann
24 821d9e43 Michael Hanselmann
25 821d9e43 Michael Hanselmann
import select
26 821d9e43 Michael Hanselmann
import signal
27 821d9e43 Michael Hanselmann
import errno
28 821d9e43 Michael Hanselmann
29 821d9e43 Michael Hanselmann
from ganeti import utils
30 821d9e43 Michael Hanselmann
31 821d9e43 Michael Hanselmann
32 821d9e43 Michael Hanselmann
class Mainloop(object):
33 821d9e43 Michael Hanselmann
  """Generic mainloop for daemons
34 821d9e43 Michael Hanselmann

35 821d9e43 Michael Hanselmann
  """
36 821d9e43 Michael Hanselmann
  def __init__(self):
37 821d9e43 Michael Hanselmann
    self._io_wait = []
38 821d9e43 Michael Hanselmann
    self._signal_wait = []
39 821d9e43 Michael Hanselmann
    self.sigchld_handler = {}
40 821d9e43 Michael Hanselmann
41 821d9e43 Michael Hanselmann
  def Run(self):
42 821d9e43 Michael Hanselmann
    # TODO: Does not yet support adding new event sources while running
43 821d9e43 Michael Hanselmann
    poller = select.poll()
44 821d9e43 Michael Hanselmann
    for (owner, fd, conditions) in self._io_wait:
45 821d9e43 Michael Hanselmann
      poller.register(fd, conditions)
46 821d9e43 Michael Hanselmann
47 821d9e43 Michael Hanselmann
    self.sigchld_handler = utils.SignalHandler([signal.SIGCHLD])
48 821d9e43 Michael Hanselmann
    try:
49 821d9e43 Michael Hanselmann
      while True:
50 821d9e43 Michael Hanselmann
        try:
51 821d9e43 Michael Hanselmann
          io_events = poller.poll(1000)
52 821d9e43 Michael Hanselmann
        except select.error, err:
53 821d9e43 Michael Hanselmann
          # EINTR can happen when signals are sent
54 821d9e43 Michael Hanselmann
          if err.args and err.args[0] in (errno.EINTR,):
55 821d9e43 Michael Hanselmann
            io_events = None
56 821d9e43 Michael Hanselmann
          else:
57 821d9e43 Michael Hanselmann
            raise
58 821d9e43 Michael Hanselmann
59 821d9e43 Michael Hanselmann
        if io_events:
60 821d9e43 Michael Hanselmann
          # Check for I/O events
61 821d9e43 Michael Hanselmann
          for (evfd, evcond) in io_events:
62 821d9e43 Michael Hanselmann
            for (owner, fd, conditions) in self._io_wait:
63 821d9e43 Michael Hanselmann
              if fd == evfd and evcond & conditions:
64 821d9e43 Michael Hanselmann
                owner.OnIO(fd, evcond)
65 821d9e43 Michael Hanselmann
66 821d9e43 Michael Hanselmann
        # Check whether signal was raised
67 821d9e43 Michael Hanselmann
        if self.sigchld_handler.called:
68 821d9e43 Michael Hanselmann
          for owner in self._signal_wait:
69 821d9e43 Michael Hanselmann
            owner.OnSignal(signal.SIGCHLD)
70 821d9e43 Michael Hanselmann
          self.sigchld_handler.Clear()
71 821d9e43 Michael Hanselmann
    finally:
72 821d9e43 Michael Hanselmann
      self.sigchld_handler.Reset()
73 821d9e43 Michael Hanselmann
      self.sigchld_handler = None
74 821d9e43 Michael Hanselmann
75 821d9e43 Michael Hanselmann
  def RegisterIO(self, owner, fd, condition):
76 821d9e43 Michael Hanselmann
    """Registers a receiver for I/O notifications
77 821d9e43 Michael Hanselmann

78 821d9e43 Michael Hanselmann
    The receiver must support a "OnIO(self, fd, conditions)" function.
79 821d9e43 Michael Hanselmann

80 821d9e43 Michael Hanselmann
    @type owner: instance
81 821d9e43 Michael Hanselmann
    @param owner: Receiver
82 821d9e43 Michael Hanselmann
    @type fd: int
83 821d9e43 Michael Hanselmann
    @param fd: File descriptor
84 821d9e43 Michael Hanselmann
    @type condition: int
85 821d9e43 Michael Hanselmann
    @param condition: ORed field of conditions to be notified
86 821d9e43 Michael Hanselmann
                      (see select module)
87 821d9e43 Michael Hanselmann

88 821d9e43 Michael Hanselmann
    """
89 821d9e43 Michael Hanselmann
    self._io_wait.append((owner, fd, condition))
90 821d9e43 Michael Hanselmann
91 821d9e43 Michael Hanselmann
  def RegisterSignal(self, owner):
92 821d9e43 Michael Hanselmann
    """Registers a receiver for signal notifications
93 821d9e43 Michael Hanselmann

94 821d9e43 Michael Hanselmann
    The receiver must support a "OnSignal(self, signum)" function.
95 821d9e43 Michael Hanselmann

96 821d9e43 Michael Hanselmann
    @type owner: instance
97 821d9e43 Michael Hanselmann
    @param owner: Receiver
98 821d9e43 Michael Hanselmann

99 821d9e43 Michael Hanselmann
    """
100 821d9e43 Michael Hanselmann
    self._signal_wait.append(owner)