"failed", "fail_reason", "cmd"]
- def __init__(self, exit_code, signal, stdout, stderr, cmd):
+ def __init__(self, exit_code, signal_, stdout, stderr, cmd):
self.cmd = cmd
self.exit_code = exit_code
- self.signal = signal
+ self.signal = signal_
self.stdout = stdout
self.stderr = stderr
- self.failed = (signal is not None or exit_code != 0)
+ self.failed = (signal_ is not None or exit_code != 0)
if self.signal is not None:
self.fail_reason = "terminated by signal %s" % self.signal
status = child.wait()
if status >= 0:
exitcode = status
- signal = None
+ signal_ = None
else:
exitcode = None
- signal = -status
+ signal_ = -status
- return RunResult(exitcode, signal, out, err, strcmd)
+ return RunResult(exitcode, signal_, out, err, strcmd)
def RemoveFile(filename):
try:
pid = int(pf.read())
except ValueError, err:
- logging.info("Can't parse pid file contents", exc_info=err)
+ logging.info("Can't parse pid file contents", exc_info=True)
return 0
return pid
pass
-def KillProcess(pid, signal=signal.SIGTERM, timeout=30):
+def KillProcess(pid, signal_=signal.SIGTERM, timeout=30):
"""Kill a process given by its pid.
@type pid: int
@param pid: The PID to terminate.
- @type signal: int
- @param signal: The signal to send, by default SIGTERM
+ @type signal_: int
+ @param signal_: The signal to send, by default SIGTERM
@type timeout: int
@param timeout: The timeout after which, if the process is still alive,
a SIGKILL will be sent. If not positive, no such checking
if not IsProcessAlive(pid):
return
- os.kill(pid, signal)
+ os.kill(pid, signal_)
if timeout <= 0:
return
end = time.time() + timeout
raise
+class FileLock(object):
+ """Utility class for file locks.
+
+ """
+ def __init__(self, filename):
+ self.filename = filename
+ self.fd = open(self.filename, "w")
+
+ def __del__(self):
+ self.Close()
+
+ def Close(self):
+ if self.fd:
+ self.fd.close()
+ self.fd = None
+
+ def _flock(self, flag, blocking, errmsg):
+ assert self.fd, "Lock was closed"
+
+ if not blocking:
+ flag |= fcntl.LOCK_NB
+
+ try:
+ fcntl.flock(self.fd, flag)
+ except IOError, err:
+ logging.exception("fcntl.flock failed")
+ if err.errno in (errno.EAGAIN, ):
+ raise errors.LockError(errmsg)
+ raise
+
+ def Exclusive(self, blocking=False):
+ """Locks the file in exclusive mode.
+
+ """
+ self._flock(fcntl.LOCK_EX, blocking,
+ "Failed to lock %s in exclusive mode" % self.filename)
+
+ def Shared(self, blocking=False):
+ """Locks the file in shared mode.
+
+ """
+ self._flock(fcntl.LOCK_SH, blocking,
+ "Failed to lock %s in shared mode" % self.filename)
+
+ def Unlock(self, blocking=True):
+ """Unlocks the file.
+
+ According to "man flock", unlocking can also be a nonblocking operation:
+ "To make a non-blocking request, include LOCK_NB with any of the above
+ operations"
+
+ """
+ self._flock(fcntl.LOCK_UN, blocking,
+ "Failed to unlock %s" % self.filename)
+
+
class SignalHandler(object):
"""Generic signal handler class.