void *oom_context; /* OOM handler context */
SilcUInt32 stack_size; /* Default stack size */
SilcUInt32 alignment; /* Memory alignment */
+ SilcAtomic32 refcnt; /* Reference counter */
#ifdef SILC_DIST_INPLACE
/* Statistics */
SilcUInt32 snum_malloc;
return NULL;
}
+ /* Reference parent */
+ SILC_LOG_DEBUG(("Reference stack %p, refcnt %d > %d", stack->parent,
+ silc_atomic_get_int32(&stack->parent->refcnt),
+ silc_atomic_get_int32(&stack->parent->refcnt) + 1));
+ silc_atomic_add_int32(&stack->parent->refcnt, 1);
+
/* Set the initial stack */
stack->stack = e;
} else {
silc_mutex_alloc(&stack->lock);
}
+ silc_atomic_init32(&stack->refcnt, 1);
+
/* Use the allocated stack in first stack frame */
stack->frame = &stack->frames[0];
stack->frame->prev = NULL;
if (!stack)
return;
- SILC_LOG_DEBUG(("Free stack %p", stack));
+ SILC_LOG_DEBUG(("Free stack %p, refcnt %d > %d", stack,
+ silc_atomic_get_int32(&stack->refcnt),
+ silc_atomic_get_int32(&stack->refcnt) - 1));
+
+ /* Unreference */
+ if (silc_atomic_sub_int32(&stack->refcnt, 1) > 0)
+ return;
if (!stack->parent) {
silc_list_start(stack->stacks);
if (stack->lock)
silc_mutex_free(stack->lock);
+ silc_atomic_uninit32(&stack->refcnt);
+
silc_free(stack);
} else {
/* Return all stack blocks to the parent */
silc_stack_unref_stack(stack->parent, e);
silc_stack_unref_stack(stack->parent, stack->stack);
+
+ /* Unreference parent */
+ silc_stack_free(stack->parent);
}
}