/* Invoke all remaining finalizers that haven't yet been run. * This is needed for strict compliance with the Java standard, * which can make the runtime guarantee that all finalizers are run. * Unfortunately, the Java standard implies we have to keep running * finalizers until there are no more left, a potential infinite loop. * YUCK. * Note that this is even more dangerous than the usual Java * finalizers, in that objects reachable from static variables * may have been finalized when these finalizers are run. * Finalizers run at this point must be prepared to deal with a * mostly broken world. * This routine is externally callable, so is called without * the allocation lock. */ GC_API void GC_finalize_all(void) { DCL_LOCK_STATE; LOCK(); while (GC_fo_entries > 0) { GC_enqueue_all_finalizers(); UNLOCK(); GC_INVOKE_FINALIZERS(); LOCK(); } UNLOCK(); }
/* Invoke all remaining finalizers that haven't yet been run. * This is needed for strict compliance with the Java standard, * which can make the runtime guarantee that all finalizers are run. * Unfortunately, the Java standard implies we have to keep running * finalizers until there are no more left, a potential infinite loop. * YUCK. * Note that this is even more dangerous than the usual Java * finalizers, in that objects reachable from static variables * may have been finalized when these finalizers are run. * Finalizers run at this point must be prepared to deal with a * mostly broken world. * This routine is externally callable, so is called without * the allocation lock. */ GC_API void GC_CALL GC_finalize_all(void) { DCL_LOCK_STATE; LOCK(); while (GC_fo_entries > 0) { GC_enqueue_all_finalizers(); UNLOCK(); GC_invoke_finalizers(); /* Running the finalizers in this thread is arguably not a good */ /* idea when we should be notifying another thread to run them. */ /* But otherwise we don't have a great way to wait for them to */ /* run. */ LOCK(); } UNLOCK(); }