All non-Async-Signal-Safe functions (e.g. malloc and die) were removed between 'fork' and 'exec' in start_command in order to avoid potential deadlocking when forking while multiple threads are running. This deadlocking is possible when a thread (other than the one forking) has acquired a lock and didn't get around to releasing it before the fork. This leaves the lock in a locked state in the resulting process with no hope of it ever being released. Add a note describing this potential pitfall before the call to 'fork()' so people working in this section of the code know to only use Async-Signal-Safe functions in the child process. Signed-off-by: Brandon Williams <bmwill@xxxxxxxxxx> --- run-command.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/run-command.c b/run-command.c index 4230c4933..1c36e692d 100644 --- a/run-command.c +++ b/run-command.c @@ -525,6 +525,15 @@ int start_command(struct child_process *cmd) prepare_cmd(&argv, cmd); childenv = prep_childenv(cmd->env); + /* + * NOTE: In order to prevent deadlocking when using threads special + * care should be taken with the function calls made in between the + * fork() and exec() calls. No calls should be made to functions which + * require acquiring a lock (e.g. malloc) as the lock could have been + * held by another thread at the time of forking, causing the lock to + * never be released in the child process. This means only + * Async-Signal-Safe functions are permitted in the child. + */ cmd->pid = fork(); failed_errno = errno; if (!cmd->pid) { -- 2.12.2.762.g0e3151a226-goog