Skip to content

forkProcess unnecessarily sets wait_foreign in hs_exit_

During normal course of action in real_main a process is terminated with a call to

    shutdownHaskellAndExit(exit_status, 0 /* !fastExit */);

which is defined as

void shutdownHaskellAndExit(int n, int fastExit)
{
    if (!fastExit) {
        // even if hs_init_count > 1, we still want to shut down the RTS
        // and exit immediately (see #5402)
        hs_init_count = 1;

        // we're about to exit(), no need to wait for foreign calls to return.
        hs_exit_(rtsFalse);
    }

    stg_exit(n);
}

However, when we call forkProcess, the child process does not terminate in this manner, but instead calls

       hs_exit();                      // clean up and exit
       stg_exit(EXIT_SUCCESS);

instead, where hs_exit is defined as

void hs_exit(void)
{
    hs_exit_(rtsTrue);
    // be safe; this might be a DLL
}

Crucially, this means that, unlike the parent, the child process does wait for foreign calls to be terminated (it calls hs_exit_ with rtsTrue instead of rtsFalse).

I don't see a reason why the child process should terminate in a different manner to the parent, so I propose to change this so that forkProcess calls shutdownHaskellAndExit, just like real_main does.

Incidentally, this is the immediate cause for #9284 (closed) , although the patch proposed in this ticket is not sufficient to solve the problems with termination of the I/O manager in the general case (but I will let Andreas explain that in more detail :).

Trac metadata
Trac field Value
Version 7.8.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information