diff --git a/tools/rosmake/src/rosmake/engine.py b/tools/rosmake/src/rosmake/engine.py index f2bf0bf6..acba0ccb 100755 --- a/tools/rosmake/src/rosmake/engine.py +++ b/tools/rosmake/src/rosmake/engine.py @@ -54,6 +54,9 @@ from . import package_stats from optparse import OptionParser +# #3883 +_popen_lock = threading.Lock() + def make_command(): """ @return: name of 'make' command @@ -371,13 +374,19 @@ class RosMakeAll: if self.ros_parallel_jobs > 0: local_env['ROS_PARALLEL_JOBS'] = "-l%d" % self.ros_parallel_jobs elif "ROS_PARALLEL_JOBS" not in os.environ: #if no environment setup and no args fall back to # cpus - local_env['ROS_PARALLEL_JOBS'] = "-l%d" % parallel_build.num_cpus() + # num_cpus check can (on OS X) trigger a Popen(), which has + #the multithreading bug we wish to avoid on Py2.7. + with _popen_lock: + local_env['ROS_PARALLEL_JOBS'] = "-l%d" % parallel_build.num_cpus() local_env['SVN_CMDLINE'] = "svn --non-interactive" cmd = ["bash", "-c", "cd %s && %s "%(self.rospack.get_path(package), make_command()) ] #UNIXONLY if argument: cmd[-1] += argument self.printer.print_full_verbose (cmd) - command_line = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=local_env, preexec_fn=self._subprocess_setup) + # #3883: make sure only one Popen command occurs at a time due to + # http://bugs.python.org/issue13817 + with _popen_lock: + command_line = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=local_env, preexec_fn=self._subprocess_setup) (pstd_out, pstd_err) = command_line.communicate() # pstd_err should be None due to pipe above return (command_line.returncode, pstd_out)