@@ -79,6 +79,9 @@ final class VMProcess extends Process
79
79
// New processes waiting to be spawned by processThread.
80
80
static final LinkedList workList = new LinkedList ();
81
81
82
+ // Number of threads waiting in waitFor() or destroy()
83
+ static int waiters ;
84
+
82
85
// Return values set by nativeReap() when a child is reaped.
83
86
// These are only accessed by processThread so no locking required.
84
87
static long reapedPid ;
@@ -109,6 +112,18 @@ private static class ProcessThread extends Thread
109
112
// Max time (in ms) we'll delay before trying to reap another child.
110
113
private static final int MAX_REAP_DELAY = 1000 ;
111
114
115
+ // Default polling delay (in ms) in "fast polling mode", i.e. when
116
+ // there are threads waiting in waitFor() or destroy().
117
+ // Can be changed using the gnu.lang.process.fastPolling system property.
118
+ private static final int DEFAULT_FAST_POLLING_DELAY = 100 ;
119
+
120
+ // Actual polling delay in fast polling mode
121
+ private static final int fastPollingDelay ;
122
+ static
123
+ {
124
+ fastPollingDelay = Integer .getInteger ("gnu.lang.process.fastPolling" , DEFAULT_FAST_POLLING_DELAY );
125
+ }
126
+
112
127
// Processes created but not yet terminated; maps Long(pid) -> VMProcess
113
128
// Only used in run() and spawn() method from this Thread, so no locking.
114
129
private final HashMap activeMap = new HashMap ();
@@ -180,7 +195,7 @@ public void run()
180
195
181
196
try
182
197
{
183
- workList .wait (MAX_REAP_DELAY );
198
+ workList .wait (waiters > 0 ? fastPollingDelay : MAX_REAP_DELAY );
184
199
}
185
200
catch (InterruptedException e )
186
201
{
@@ -330,15 +345,35 @@ public InputStream getErrorStream()
330
345
return stderr ;
331
346
}
332
347
333
- public synchronized int waitFor () throws InterruptedException
348
+ private void addWaiter ()
334
349
{
335
350
synchronized (workList )
336
351
{
352
+ waiters ++;
337
353
workList .notify ();
338
354
}
355
+ }
356
+
357
+ private void removeWaiter ()
358
+ {
359
+ synchronized (workList )
360
+ {
361
+ waiters --;
362
+ }
363
+ }
339
364
340
- while (state != TERMINATED )
341
- wait ();
365
+ public synchronized int waitFor () throws InterruptedException
366
+ {
367
+ try
368
+ {
369
+ addWaiter ();
370
+ while (state != TERMINATED )
371
+ wait ();
372
+ }
373
+ finally
374
+ {
375
+ removeWaiter ();
376
+ }
342
377
return exitValue ;
343
378
}
344
379
@@ -356,12 +391,9 @@ public synchronized void destroy()
356
391
357
392
nativeKill (pid );
358
393
359
- synchronized (workList )
360
- {
361
- workList .notify ();
362
- }
363
-
394
+ addWaiter ();
364
395
waitForStateUninterruptibly (TERMINATED , false );
396
+ removeWaiter ();
365
397
}
366
398
367
399
private void waitForStateUninterruptibly (int state , boolean eq )
0 commit comments