Hi Peter,
Thanks for the comments...
On 6/26/2014 4:55 AM, Peter Levart wrote:
On 06/26/2014 12:05 AM, David M. Lloyd wrote:
On 06/25/2014 04:52 PM, roger riggs wrote:
Hi,
The next step for JEP 102, Process API Updates is to provide an API to
enumerate the hierarchy of processes and to be able to terminate a
process tree.
This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1]
includes:
- ProcessHandle class to provide handles to processes, their
children,
parent, process id and liveness
- Process extends ProcessHandle and inherits the new behaviors
- Method destroyProcessTree() terminates a process tree
Additional functions related to termination and information about
processes
will be added in a later update.
Comments appreciated, Roger
I still have a not-great feeling about the lack of atomicity inherent
in these operations. At least when you're dealing with direct child
processes (on UNIX-likes), there is some measure of control, in that
a process is zombified until reaped by wait() and friends.
Also I have a much higher level of concern about
destroyProcessTree(), which I don't think has any place in this API.
Control of any process belongs solely with their parent (or PID 1),
in my opinion.
Those concerns aside, what about making the allChildren() and
allProcesses() methods lazy in some way?
Hi Roger, David,
- Will there be a guarantee that ProcessHandle objects returned from
factory methods: |current()|
<http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#current-->,
|of(long)|
<http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#of-long->,
|children()|
<http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#children-->,
|allChildren()|
<http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#allChildren-->,
|getParent()|
<http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#getParent-->
and |allProcesses()|
<http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#allProcesses-->
representing those processes that were started by ProcessBuilder API
are actually the same Process objects that were returned from the
ProcessBuilder API? The Process object can be viewed as a proxy of an
OS process so as long as we have a reference to it, we can obtain it's
exit status even though it has already been waited for (reaped) and we
can reliably terminate it, because Process object is tracking the
state of OS process and only forwards the termination request if it
knows the OS process is still alive or zombified and so minimizes the
probability to kill wrong process that just reused the same pid.
The initial design does not have them returning Process instances.
Process instances are capabilities and their reference accessibility is
currently controlled
by the code that created the Process. If ProcessHandle gave out those
Process instances
it would break existing encapsulation.
The following expression: ProcessHandle.current().children() would
therefore return just canonicalized Process objects (unless some
native code embedded in the JVM process started sub-processes too).
If returning canonicalized Process objects from factory methods is not
desirable (some part of the program could mess with Input/Output
streams of Process-es it did not have access to before), then perhaps
ProcessHandle representing a process created by ProcessBuilder API
would just have an internal private reference to the Process object to
which it would forward method invocations...
yes, that would break encapsulation; not desirable and potential
security issue.
And yes, the implementation can maintain the association and delegate
the behavior.
It does not/should not make any difference in practice.
Regardless of whether the TERM or KILL signal is delivered by an external
process or via the ProcessHandle API, the Process mechanics should be
the same.
An application using the Process should see the same behavior, cleanup
and termination, in either case.
- There is an inconsistency in the javadoc for
ProcessHandle.destroyForcibly():
public abstractProcessHandle
<http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html>
destroyForcibly()
Kills the process. The process represented by this |ProcessHandle|
object is forcibly terminated. If the process is not alive no action
is taken.
Note: The process may not terminate immediately. i.e. |isAlive()| may
return true for a brief period after |destroyForcibly()| is called.
This method may be chained to |waitFor()| if needed.
...the method has a co-variant return type and there's no waitFor()
method on the ProcessHandle. Why not? If ProcessHandle is a (or
delegates to) Process then it could use it's waitFor(), if it is just
a "foreign" ProcessHandle it could be implemented as a poll-ing wait
for the isAlive() to return false...
I plan to address waitFor of ProcessHandle a bit later due to the
complexities
previously discussed for non-Process processes and when I can spend more
time
on the implementations and alternatives.
Also requested are either Future style returns or lambda enabled onExit
behavior.
- Will there not be any destroyGracefully() method (which would be a
no-op on platforms not supporting graceful termination)?
An alternative is to add a method to report whether destroy is graceful
or not.
Either way an application needs to be aware of whether it worked or not so
it can take some alternate action.
- Depending on the OS facilities used to obtain process information
(/proc/<pid> ?) there might be some other attributes already
available. The name of a process would be nice to have.
yep, also on the list and it builds naturally on top of ProcessHandle
when the relationship between ProcessHandle and Process is settled.
Thanks, Roger
Regards, Peter