Skip to content

Commit e503cd6

Browse files
bmwillgitster
authored andcommitted
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>
1 parent 53fa675 commit e503cd6

1 file changed

Lines changed: 9 additions & 0 deletions

File tree

run-command.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,15 @@ int start_command(struct child_process *cmd)
537537
prepare_cmd(&argv, cmd);
538538
childenv = prep_childenv(cmd->env);
539539

540+
/*
541+
* NOTE: In order to prevent deadlocking when using threads special
542+
* care should be taken with the function calls made in between the
543+
* fork() and exec() calls. No calls should be made to functions which
544+
* require acquiring a lock (e.g. malloc) as the lock could have been
545+
* held by another thread at the time of forking, causing the lock to
546+
* never be released in the child process. This means only
547+
* Async-Signal-Safe functions are permitted in the child.
548+
*/
540549
cmd->pid = fork();
541550
failed_errno = errno;
542551
if (!cmd->pid) {

0 commit comments

Comments
 (0)