Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorC. Scott Ananian <cscott@laptop.org>2008-09-17 18:56:33 (GMT)
committer C. Scott Ananian <cscott@laptop.org>2008-09-18 15:14:41 (GMT)
commit28586edb2f1de61abc0cce9ece3419258df27696 (patch)
tree85bf633df419a6afb684ece7b13d42a3ed5ae8d3 /src
parentf2a8948bf15a5e669f02aa26d1e267ad11cb0ac8 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/sugar/activity/activityfactory.py42
1 files changed, 30 insertions, 12 deletions
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()