Skip to content

Commit 523b3dd

Browse files
committed
GH77: Added note.'
1 parent 94a2140 commit 523b3dd

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

cbits/runProcess.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,38 @@ createCompletionPort (HANDLE hJob)
553553
return ioPort;
554554
}
555555

556+
/* Note [Windows exec interaction]
557+
558+
The basic issue that process jobs tried to solve is this:
559+
560+
Say you have two programs A and B. Now A calls B. There are two ways to do this.
561+
562+
1) You can use the normal CreateProcess API, which is what normal Windows code do.
563+
Using this approach, the current waitForProcess works absolutely fine.
564+
2) You can call the emulated POSIX function _exec, which of course is supposed to
565+
allow the child process to replace the parent.
566+
567+
With approach 2) waitForProcess falls apart because the Win32's process model does
568+
not allow this the same way as linux. _exec is emulated by first making a call to
569+
CreateProcess to spawn B and then immediately exiting from A. So you have two
570+
different processes.
571+
572+
waitForProcess is waiting on the termination of A. Because A is immediately killed,
573+
waitForProcess will return even though B is still running. This is why for instance
574+
the GHC testsuite on Windows had lots of file locked errors.
575+
576+
This approach creates a new Job and assigned A to the job, but also all future
577+
processes spawned by A. This allows us to listen in on events, such as, when all
578+
processes in the job are finished, but also allows us to propagate exit codes from
579+
_exec calls.
580+
581+
The only reason we need this at all is because we don't interact with just actual
582+
native code on Windows, and instead have a lot of ported POSIX code.
583+
584+
The Job handle is returned to the user because Jobs have additional benefits as well,
585+
such as allowing you to specify resource limits on the to be spawned process.
586+
*/
587+
556588
ProcHandle
557589
runInteractiveProcess (wchar_t *cmd, wchar_t *workingDirectory,
558590
wchar_t *environment,
@@ -668,8 +700,9 @@ runInteractiveProcess (wchar_t *cmd, wchar_t *workingDirectory,
668700
dwFlags |= CREATE_NEW_CONSOLE;
669701
}
670702

671-
// If we're going to use a job object, then we have to create
672-
// the thread suspended.
703+
/* If we're going to use a job object, then we have to create
704+
the thread suspended.
705+
See Note [Windows exec interaction]. */
673706
if (useJobObject)
674707
{
675708
dwFlags |= CREATE_SUSPENDED;

0 commit comments

Comments
 (0)