RFR 9: 8078099 : (process) ProcessHandle should uniquely identify processes

Volker Simonis volker.simonis at gmail.com
Tue Jul 7 07:29:34 UTC 2015


Hi Roger,

sorry but I only now noticed this RFR. Can you please temporary hold
this change back. I think it needs some adjustments on AIX. I'll look
into it today and let you know.

Thanks,
Volker



On Mon, Jul 6, 2015 at 4:47 PM, Roger Riggs <Roger.Riggs at oracle.com> wrote:
> Hi Peter,
>
> Thanks for reviewing the new implementation.
>
> The idea to pre-allocate the buffer based on the size of the output arrays
> passed for output
> will not work as desired.
> The same native code entry point is used whether it is a query for all
> processes or
> just the immediate children.  In either case, the buffer for sysctl needs to
> be
> large enough to accommodate all of the OS threads; its not a function of the
> output array size.
>
> With respect to the buffer allocation on OS X, I might see the point of a
> retry
> when sysctl returns ENOMEM;
>
>
> I don't think its particularly worthwhile to add the native code to retry in
> the case
> of ENOMEM. The OSX doc for sysctrl does indicate it tries to round up
> to avoid a subsequent failure.
> The ProcessHandle API already cautions that the list of processes is dynamic
> and that processes may started or terminate concurrently with the call  to
> children/allChildren.
> So if the sysctl returns ENOMEM indicating not all the processes fit; the
> ones
> that do fit within in the allocated buffer are valid at that point in time.
> If there are extras that do not fit in the buffer they are likely to be
> 'newer'
> processes and can be considered to have been started 'after' the
> children/allChildren invocation.
> So I propose to change the error checking to consider ENOMEM as a
> non-exceptional
> return and return the processes available.
>
> Thanks, Roger
>
>
>
>
> On 7/2/2015 3:32 AM, Peter Levart wrote:
>>
>> Hi Roger,
>>
>> I looked at the code briefly and have the following comments:
>>
>> For ProcessHandleImpl_macosx.c, in method getProcessPids0:
>>
>>  224     // Get buffer size needed to read all processes
>>  225     int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
>>  226     if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0) {
>>  227         JNU_ThrowByNameWithLastError(env,
>>  228             "java/lang/RuntimeException", "sysctl failed");
>>  229         return -1;
>>  230     }
>>  231
>>  232     // Allocate buffer big enough for all processes
>>  233     void *buffer = malloc(bufSize);
>>  234     if (buffer == NULL) {
>>  235         JNU_ThrowOutOfMemoryError(env, "malloc failed");
>>  236         return -1;
>>  237     }
>>  238
>>  239     // Read process info for all processes
>>  240     if (sysctl(mib, 4, buffer, &bufSize, NULL, 0) < 0) {
>>  241         JNU_ThrowByNameWithLastError(env,
>>  242             "java/lang/RuntimeException", "sysctl failed");
>>  243         free(buffer);
>>  244         return -1;
>>  245     }
>>
>> ... the 1st call to sysctl is used to measure the size of the needed
>> buffer and the 2nd call fills-in the buffer. The documentation for sysctl
>> says:
>>
>> "     The information is copied into the buffer specified by oldp. The
>> size of the buffer is given by the
>>      location specified by oldlenp before the call, and that location
>> gives the amount of data copied after
>>      a successful call and after a call that returns with the error code
>> ENOMEM.  If the amount of data
>>      available is greater than the size of the buffer supplied, the call
>> supplies as much data as fits in
>>      the buffer provided and returns with the error code ENOMEM. If the
>> old value is not desired, oldp and
>>      oldlenp should be set to NULL.
>>
>>      The size of the available data can be determined by calling sysctl()
>> with the NULL argument for oldp.
>>      The size of the available data will be returned in the location
>> pointed to by oldlenp.  For some opera-tions, operations,
>>      tions, the amount of space may change often.  For these operations,
>> the system attempts to round up so
>>      that the returned size is large enough for a call to return the data
>> shortly thereafter."
>>
>> So while not very probable, it can happen that you get ENOMEM from 2nd
>> call because of underestimated buffer size. Would it be better to retry
>> (re)allocation of buffer and 2nd call in a loop with new estimation returned
>> from previous call while the error is ENOMEM?
>>
>> Another suggestion: What would it be if the buffer size estimation was not
>> computed by a call to sysctl with NULL buffer, but was taken from the
>> passed-in resulting array size(s). In case the user passes-in arrays of
>> sufficient size, you can avoid double invocation of sysctl. Also, if ENOMEM
>> happens, you can just return the result obtained and the new estimation - no
>> looping in native code. The UNIX, Solaris and Windows variants look good.
>>
>> Regards, Peter
>>
>> On 06/22/2015 05:10 PM, Roger Riggs wrote:
>>>
>>> Please review changes to ProcessHandle implementation to uniquely
>>> identify
>>> processes based on the start time provided by the OS. It addresses the
>>> issue
>>> of PID reuse.
>>>
>>> This is the implementation of the ProcessHandle.equals() spec change in
>>>     8129344 : (process) ProcessHandle instances should define equals and
>>> be value-based
>>>
>>> Webrev:
>>> http://cr.openjdk.java.net/~rriggs/webrev-starttime-8078099/
>>>
>>> Issue:
>>> https://bugs.openjdk.java.net/browse/JDK-8078099
>>>
>>> Thanks, Roger
>>>
>>
>



More information about the core-libs-dev mailing list