44
44
import java .lang .ref .Reference ;
45
45
import java .lang .ref .ReferenceQueue ;
46
46
import java .lang .ref .WeakReference ;
47
+ import java .util .ArrayList ;
47
48
import java .util .Arrays ;
48
49
import java .util .concurrent .ConcurrentHashMap ;
49
50
import java .util .concurrent .ConcurrentMap ;
@@ -363,10 +364,10 @@ public final void markReleased() {
363
364
* This implements the proper way to free the allocated resources associated with the
364
365
* reference.
365
366
*/
366
- public abstract AsyncHandler . AsyncAction release ();
367
+ public abstract AsyncAction release ();
367
368
}
368
369
369
- static class SharedFinalizerErrorCallback implements AsyncHandler . AsyncAction {
370
+ static class SharedFinalizerErrorCallback implements AsyncAction {
370
371
371
372
private final Exception exception ;
372
373
private final FinalizableReference referece ; // problematic reference
@@ -382,6 +383,24 @@ public void execute(PythonContext context) {
382
383
}
383
384
}
384
385
386
+ private static final class AsyncActionsList implements AsyncAction {
387
+ private final AsyncAction [] array ;
388
+
389
+ public AsyncActionsList (AsyncAction [] array ) {
390
+ this .array = array ;
391
+ }
392
+
393
+ public void execute (PythonContext context ) {
394
+ for (AsyncAction action : array ) {
395
+ try {
396
+ action .execute (context );
397
+ } catch (RuntimeException e ) {
398
+ ExceptionUtils .printPythonLikeStackTrace (e );
399
+ }
400
+ }
401
+ }
402
+ }
403
+
385
404
/**
386
405
* We register the Async action once on the first encounter of a creation of
387
406
* {@link FinalizableReference}. This will reduce unnecessary Async thread load when there
@@ -395,17 +414,26 @@ public void registerAsyncAction() {
395
414
} catch (InterruptedException e ) {
396
415
Thread .currentThread ().interrupt ();
397
416
}
398
- if (reference instanceof FinalizableReference ) {
399
- FinalizableReference object = (FinalizableReference ) reference ;
400
- try {
401
- liveReferencesSet .remove (object );
402
- if (object .isReleased ()) {
403
- return null ;
417
+ ArrayList <AsyncAction > actions = new ArrayList <>();
418
+ do {
419
+ if (reference instanceof FinalizableReference ) {
420
+ FinalizableReference object = (FinalizableReference ) reference ;
421
+ try {
422
+ liveReferencesSet .remove (object );
423
+ if (!object .isReleased ()) {
424
+ AsyncAction action = object .release ();
425
+ if (action != null ) {
426
+ actions .add (action );
427
+ }
428
+ }
429
+ } catch (Exception e ) {
430
+ actions .add (new SharedFinalizerErrorCallback (object , e ));
404
431
}
405
- return object .release ();
406
- } catch (Exception e ) {
407
- return new SharedFinalizerErrorCallback (object , e );
408
432
}
433
+ reference = queue .poll ();
434
+ } while (reference != null );
435
+ if (!actions .isEmpty ()) {
436
+ return new AsyncActionsList (actions .toArray (new AsyncAction [0 ]));
409
437
}
410
438
return null ;
411
439
});
0 commit comments