Skip to content

Instantly share code, notes, and snippets.

@illusory0x0
Created May 29, 2025 12:38
Show Gist options
  • Select an option

  • Save illusory0x0/e3639d8b1fd115497e422fa327dfabeb to your computer and use it in GitHub Desktop.

Select an option

Save illusory0x0/e3639d8b1fd115497e422fa327dfabeb to your computer and use it in GitHub Desktop.
struct arc {
int32_t rc;
uv_mutex_t mutex;
};
typedef void* moonbit_reference_t;
struct arc_ref {
struct arc arc;
moonbit_reference_t ref;
};
typedef arc_ref *moonbit_arc_ref_payload;
typedef moonbit_arc_ref_payload* moonbit_arc_ref_t;
void moonbit_uv_reference_finalize(void* object) {
moonbit_arc_ref_t obj = (moonbit_arc_ref_t)(object);
if (obj) {
moonbit_arc_ref_payload arcref_payload = *obj;
// Critical Section BEGIN
uv_mutex_lock( &arcref_payload->arc.mutex);
int32_t rc = arcref_payload->arc.rc;
moonbit_uv_trace("mutex->block->arc = %d -> %d\n", rc, rc - 1);
arcref_payload->arc.rc -= 1;
uv_mutex_unlock( &arcref_payload->arc.mutex);
// Critical Section END
if (rc > 1) {
return;
}
// now this callee is unique owner
uv_mutex_destroy(&arcref_payload->arc.mutex);
moonbit_decref(arcref_payload->ref);
free(arcref_payload);
}
}
void mooonbit_uv_reference_make(moonbit_reference_t* ref) {
moonbit_arc_ref_t res = (moonbit_arc_ref_t)moonbit_make_external_object(
moonbit_uv_reference_finalize,
sizeof(moonbit_arc_ref_payload)
);
moonbit_arc_ref_payload arcref_payload = (moonbit_arc_ref_payload)malloc(sizeof(struct arc_ref));
*res = arcref_payload;
arcref_payload->ref = ref;
arcref_payload->arc.rc = 1;
uv_mutex_init(&arcref_payload->arc.mutex);
}
moonbit_arc_ref_t mooonbit_uv_reference_share_payload(moonbit_arc_ref_t self) {
moonbit_arc_ref_t res = (moonbit_arc_ref_t)moonbit_make_external_object(
moonbit_uv_reference_finalize,
sizeof(moonbit_arc_ref_payload)
);
moonbit_arc_ref_payload arcref_payload = *self;
// Critical Section BEGIN
uv_mutex_lock(&arcref_payload->arc.mutex);
arcref_payload->arc.rc += 1;
uv_mutex_unlock(&arcref_payload->arc.mutex);
// Critical Section END
*res = arcref_payload;
moonbit_decref(self);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment