From 28586edb2f1de61abc0cce9ece3419258df27696 Mon Sep 17 00:00:00 2001 From: C. Scott Ananian Date: Wed, 17 Sep 2008 18:56:33 +0000 Subject: 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. --- (limited to 'src/sugar/activity/activityfactory.py') diff --git a/src/sugar/activity/activityfactory.py b/src/sugar/activity/activityfactory.py index 75bc769..42ab468 100644 --- a/src/sugar/activity/activityfactory.py +++ b/src/sugar/activity/activityfactory.py @@ -54,15 +54,18 @@ _RAINBOW_SERVICE_NAME = "org.laptop.security.Rainbow" _RAINBOW_ACTIVITY_FACTORY_PATH = "/" _RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow" -_children_pid = [] - -def _sigchild_handler(signum, frame): - for child_pid in _children_pid: - pid, status_ = os.waitpid(child_pid, os.WNOHANG) - if pid > 0: - _children_pid.remove(pid) - -signal.signal(signal.SIGCHLD, _sigchild_handler) +# helper method to close all filedescriptors +# borrowed from subprocess.py +try: + MAXFD = os.sysconf("SC_OPEN_MAX") +except: + MAXFD = 256 +def _close_fds(): + for i in xrange(3, MAXFD): + try: + os.close(i) + except: + pass def create_activity_id(): """Generate a new, unique ID for this activity""" @@ -245,9 +248,24 @@ class ActivityCreationHandler(gobject.GObject): self._handle.uri) if not self._use_rainbow: - p = subprocess.Popen(command, env=environ, cwd=activity.path, - stdout=log_file, stderr=log_file) - _children_pid.append(p.pid) + # use gobject spawn functionality, so that zombies are + # automatically reaped by the gobject event loop. + 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: log_file.close() system_bus = dbus.SystemBus() -- cgit v0.9.1