GC_toggleref_array_size = w;
}
+/* Finalizer proc support */
+static void (*GC_object_finalized_proc) (GC_PTR obj);
+
+void
+GC_set_finalizer_notify_proc (void (*proc) (GC_PTR obj))
+{
+ GC_object_finalized_proc = proc;
+}
+
static void push_and_mark_object (GC_PTR p)
{
fo_set_next(prev_fo, next_fo);
}
GC_fo_entries--;
+
+ if (GC_object_finalized_proc)
+ GC_object_finalized_proc (real_ptr);
+
/* Add to list of objects awaiting finalization. */
fo_set_next(curr_fo, GC_finalize_now);
GC_finalize_now = curr_fo;
GC_API void GC_toggleref_register_callback GC_PROTO((int (*proccess_toggleref) (GC_PTR obj)));
GC_API void GC_toggleref_add (GC_PTR object, int strong_ref);
+/* finalizer callback support */
+GC_API void GC_set_finalizer_notify_proc GC_PROTO((void (*object_finalized) (GC_PTR obj)));
+
+
/* Returns !=0 if GC_invoke_finalizers has something to do. */
GC_API int GC_should_invoke_finalizers GC_PROTO((void));
static void
register_test_toggleref_callback (void);
+#define BOEHM_GC_BIT_FINALIZER_AWARE 1
+static MonoGCFinalizerCallbacks fin_callbacks;
+
static void
mono_gc_warning (char *msg, GC_word arg)
{
guint
mono_gc_get_vtable_bits (MonoClass *class)
{
+ if (fin_callbacks.is_class_finalization_aware) {
+ if (fin_callbacks.is_class_finalization_aware (class))
+ return BOEHM_GC_BIT_FINALIZER_AWARE;
+ }
return 0;
}
mono_gc_toggleref_register_callback (test_toggleref_callback);
}
+static gboolean
+is_finalization_aware (MonoObject *obj)
+{
+ MonoVTable *vt = obj->vtable;
+ return (vt->gc_bits & BOEHM_GC_BIT_FINALIZER_AWARE) == BOEHM_GC_BIT_FINALIZER_AWARE;
+}
+
+static void
+fin_notifier (MonoObject *obj)
+{
+ if (is_finalization_aware (obj))
+ fin_callbacks.object_queued_for_finalization (obj);
+}
+
+void
+mono_gc_register_finalizer_callbacks (MonoGCFinalizerCallbacks *callbacks)
+{
+ if (callbacks->version != MONO_GC_FINALIZER_EXTENSION_VERSION)
+ g_error ("Invalid finalizer callback version. Expected %d but got %d\n", MONO_GC_FINALIZER_EXTENSION_VERSION, callbacks->version);
+
+ fin_callbacks = *callbacks;
+
+ GC_set_finalizer_notify_proc ((void (*) (GC_PTR))fin_notifier);
+}
+
#endif /* no Boehm GC */