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:
parent
f2a8948bf1
commit
28586edb2f
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user