Hi Martin,

On 6/15/2015 6:19 PM, Martin Buchholz wrote:
OK, it wasn't clear to me this code was only running in a forkjoin pool.
There are several layers in play.
The ProcessHandleImpl.completion() method returns a CF that is completed on the ReaperThread.
That CF is unique to the PID.
a. When the process is spawned; (ProcessImpl.initStreams), its the CF.handle() contains
the function to store the exitcode and sets hasExited.
b. If onExit is used by the application, handleAsync() creates the CF returned from
onExit and is mostly a no-op except for  the exitcode synchronization.

These two completions run concurrently; the purpose of using handleAsync for the onExit
case is to ensure the reaper thread only handles lightweight known tasks.

Hmmm ... is there guidance on how tasks in a forkjoin pool should handle InterruptedException?
I haven't unraveled it; it seems to just set a flag in the task and otherwise ignore it.

It should be very rare for forkjoin threads to be externally interrupted (task cancellation does not interrupt), so rare that maybe it should be interpreted as an emergency request and failing with InterruptedException is best?
I don't think we have any conventions for that case.

I've obviously lost touch with what this modern Process code is doing ... but:

It looks fishy that you have a future that takes an exitStatus but calls waitFor in its body. If the exitStatus is already available, then the process must (should?) have already completed?
I can rename it to unusedExitValue; it is unused.
yes, the process has completed but the ProcessImpl.exitcode field may not have been updated (yet). (There may be no onExit handler if the application didn't call it so it can't do any
of the mandatory updates).


It looks fishy to call handle (which gets any exception thrown) but then the exception is discarded.
That's in the CF method signature(s); there never is any Throwable from the process reaper
(ProcessHandleImpl:119).

shouldReap looks weird to me - I'd expect to always have exactly one grim reaper thread per Process that always does the reaping.
Yes but the reaper mechanism is also used for arbitrary processes (that are not reaped). The ProcessHandleImpl.completion() method handles both non-reaping and reaping.

But yeah, I already had my chance to review this code ... maybe it's time for me to retire from java.lang.Process.
An extra set of eyes on the code is helpful. You see things I don't.

Thanks, Roger



On Mon, Jun 15, 2015 at 2:21 PM, Roger Riggs <roger.ri...@oracle.com <mailto:roger.ri...@oracle.com>> wrote:

    Hi Martin,

    Since the function is called from the FJ pool; what would result
    from propagating the interrupt?
    The FJPool reports the interrupted to the task but otherwise just
    clears it.
    It does not affect the completion status.

    Since it is known that the process has terminated and is only
    waiting for the
    Thread in ProcessImpl to post the status; it cannot/should not
    proceed until the
    exitValue is valid.

    The webrev has been updated to propagate the interrupted status
    but it will
    likely be ignored/discarded.

    Roger




    On 6/15/2015 4:46 PM, Martin Buchholz wrote:
    if you do get interrupted, the interrupt is swallowed, which
    seems wrong.

    Other waiting methods have "uninterruptible" variants, that
    restore the interrupt status, like
    Semaphore.acquireUninterruptibly.  Should there be a
    Process.waitForUninterruptibly?

    On Mon, Jun 15, 2015 at 1:37 PM, Roger Riggs
    <roger.ri...@oracle.com <mailto:roger.ri...@oracle.com>> wrote:

        Please review a fix for a (Unix) race condition for the exit
        status of Process.onExit.
        And some source cleanup of OnExitTest.

        Webrev:
        http://cr.openjdk.java.net/~rriggs/webrev-race-8086208/
        <http://cr.openjdk.java.net/%7Erriggs/webrev-race-8086208/>

        Issue:
        https://bugs.openjdk.java.net/browse/JDK-8086208

        Roger





Reply via email to