Opened 10 years ago
Last modified 6 years ago
#687 new enhancement
use posix_spawn for ccl:run-program
Reported by: | rme | Owned by: | rme |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | other | Version: | trunk |
Keywords: | Cc: |
Description
When the operating system supports it, use posix_spawn in lieu of fork/exec in the implementation of ccl:run-program.
Change History (3)
comment:1 Changed 9 years ago by rme
comment:2 Changed 6 years ago by rme
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5049299
The above link describes a strategy whereby posix_spawn starts a little helper program that does the file descriptor manipulation, and then does the fork() and exec().
Or maybe we just forget about this complicated mess and keep on using fork() in ccl.
comment:3 Changed 6 years ago by rme
Apple's posix_spawnattr_setflags() accepts a flag named POSIX_SPAWN_CLOEXEC_DEFAULT. The man page says:
If this bit is set, then only file descriptors explicitly described by the file_actions argument are available in the spawned process; all of the other file descriptors are automatically closed in the spawned process.
It looks like this showed up in 10.7.2 or thereabouts.
http://lists.apple.com/archives/Darwin-dev/2011/Mar/msg00005.html describes a race involving closing file descriptors that we may want to watch out for.
On Mar 1, 2011, at 1:54 AM, Chris Suter wrote:
Doesn't work. If another thread is concurrently opening or closing descriptors during your scan and your call to posix_spawn(), you'll fail.
another thread closes that descriptor before you call posix_spawn(), then posix_spawn() will return EBADF and not spawn the process.
descriptor, and another thread opens that descriptor before you call posix_spawn(), then the child process will have an unexpectedly open descriptor. This can lead to deadlocks elsewhere.
Just like you said above: you loop through all 1024 (or however many) file descriptors and close everything except the ones you want. This is safe in the fork/exec case because there's only one thread in the child after fork(), so there's no race with other manipulation of the child's descriptors.