for (;;) {
gboolean success;
- desc = (Descriptor *) get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1);
+ desc = (Descriptor *) mono_get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1);
if (desc) {
Descriptor *next = desc->next;
success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, next, desc) == desc);
g_assert (desc->anchor.data.state != STATE_FULL);
- mono_lock_free_queue_node_free (&desc->node);
+ mono_lock_free_queue_node_unpoison (&desc->node);
mono_lock_free_queue_enqueue (&desc->heap->sc->partial, &desc->node);
}
g_assert (old_anchor.data.state != STATE_EMPTY);
if (InterlockedCompareExchangePointer ((gpointer * volatile)&heap->active, NULL, desc) == desc) {
- /* We own it, so we free it. */
- desc_retire (desc);
+ /*
+ * We own desc, check if it's still empty, in which case we retire it.
+ * If it's partial we need to put it back either on the active slot or
+ * on the partial list.
+ */
+ if (desc->anchor.data.state == STATE_EMPTY) {
+ desc_retire (desc);
+ } else if (desc->anchor.data.state == STATE_PARTIAL) {
+ if (InterlockedCompareExchangePointer ((gpointer * volatile)&heap->active, desc, NULL) != NULL)
+ heap_put_partial (desc);
+
+ }
} else {
/*
* Somebody else must free it, so we do some