Trac #8532: remove SIGCHLD handler, which interacts poorly with threads.

Threads and signals don't get along too well together.  Instead, use
gobject's spawn_async functionality which already has the necessary zombie-
reaping integrated into the gobject event loop.
This commit is contained in:
C. Scott Ananian 2008-09-17 14:56:33 -04:00
parent f2a8948bf1
commit 28586edb2f

View File

@ -54,15 +54,18 @@ _RAINBOW_SERVICE_NAME = "org.laptop.security.Rainbow"
_RAINBOW_ACTIVITY_FACTORY_PATH = "/" _RAINBOW_ACTIVITY_FACTORY_PATH = "/"
_RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow" _RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow"
_children_pid = [] # helper method to close all filedescriptors
# borrowed from subprocess.py
def _sigchild_handler(signum, frame): try:
for child_pid in _children_pid: MAXFD = os.sysconf("SC_OPEN_MAX")
pid, status_ = os.waitpid(child_pid, os.WNOHANG) except:
if pid > 0: MAXFD = 256
_children_pid.remove(pid) def _close_fds():
for i in xrange(3, MAXFD):
signal.signal(signal.SIGCHLD, _sigchild_handler) try:
os.close(i)
except:
pass
def create_activity_id(): def create_activity_id():
"""Generate a new, unique ID for this activity""" """Generate a new, unique ID for this activity"""
@ -245,9 +248,24 @@ class ActivityCreationHandler(gobject.GObject):
self._handle.uri) self._handle.uri)
if not self._use_rainbow: if not self._use_rainbow:
p = subprocess.Popen(command, env=environ, cwd=activity.path, # use gobject spawn functionality, so that zombies are
stdout=log_file, stderr=log_file) # automatically reaped by the gobject event loop.
_children_pid.append(p.pid) def child_setup():
# clone logfile.fileno() onto stdout/stderr
os.dup2(log_file.fileno(), 1)
os.dup2(log_file.fileno(), 2)
# close all other fds
_close_fds()
# we need to sanitize and str-ize the various bits which
# dbus gives us.
gobject.spawn_async([str(s) for s in command],
envp=['%s=%s' % (k, str(v))
for k, v in environ.items()],
working_directory=str(activity.path),
child_setup=child_setup,
flags=(gobject.SPAWN_SEARCH_PATH |
gobject.SPAWN_LEAVE_DESCRIPTORS_OPEN))
log_file.close()
else: else:
log_file.close() log_file.close()
system_bus = dbus.SystemBus() system_bus = dbus.SystemBus()