+static void
+free_context (void *user_data)
+{
+ ContextStaticData *data = user_data;
+
+ mono_threads_lock ();
+
+ /*
+ * There is no guarantee that, by the point this reference queue callback
+ * has been invoked, the GC handle associated with the object will fail to
+ * resolve as one might expect. So if we don't free and remove the GC
+ * handle here, free_context_static_data_helper () could end up resolving
+ * a GC handle to an actually-dead context which would contain a pointer
+ * to an already-freed static data segment, resulting in a crash when
+ * accessing it.
+ */
+ g_hash_table_remove (contexts, GUINT_TO_POINTER (data->gc_handle));
+
+ mono_threads_unlock ();
+
+ mono_gchandle_free (data->gc_handle);
+ mono_free_static_data (data->static_data);
+ g_free (data);
+}
+