When dereferencing a weak link we check whether bridge processing is
in progress. If it is, we wait for it to finish. This ensures that
we never follow weak links to dead objects before bridge processing
can null them.
static int current_time;
-static gboolean bridge_processing_in_progress = FALSE;
+gboolean bridge_processing_in_progress = FALSE;
void
mono_gc_wait_for_bridge_processing (void)
if (!registered_bridges.size)
return;
+ /*
+ * bridge_processing_in_progress must be set with the world
+ * stopped. If not there would be race conditions.
+ */
g_assert (!bridge_processing_in_progress);
bridge_processing_in_progress = TRUE;
void *ptr = *link_addr;
if (!ptr)
return NULL;
+
+ /*
+ * During the second bridge processing step the world is
+ * running again. That step processes all weak links once
+ * more to null those that refer to dead objects. Before that
+ * is completed, those links must not be followed, so we
+ * conservatively wait for bridge processing when any weak
+ * link is dereferenced.
+ */
+ if (G_UNLIKELY (bridge_processing_in_progress))
+ mono_gc_wait_for_bridge_processing ();
+
return (MonoObject*) REVEAL_POINTER (ptr);
}
extern unsigned int sgen_global_stop_count;
+extern gboolean bridge_processing_in_progress;
+
#define SGEN_ALLOC_ALIGN 8
#define SGEN_ALLOC_ALIGN_BITS 3