diff options
author | Brandon Williams <bmwill@google.com> | 2017-04-19 16:13:26 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-04-20 17:55:32 -0700 |
commit | e503cd6ed336d70d716e194ef6c5469330bea9da (patch) | |
tree | 85e6ecdb24137b1d66f336f2e7efbe5615edc468 /run-command.c | |
parent | 53fa6753b30c4fb4ea768d16d41d723ea19a3b00 (diff) | |
download | git-e503cd6ed336d70d716e194ef6c5469330bea9da.tar.gz |
run-command: add note about forking and threading
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@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'run-command.c')
-rw-r--r-- | run-command.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/run-command.c b/run-command.c index 615b6e9c9c..df1edd963f 100644 --- a/run-command.c +++ b/run-command.c @@ -537,6 +537,15 @@ fail_pipe: 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) { |