1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-06 00:36:17 +00:00

Fix reference counting for threaded abstract types.

Was very borked. The sweep phase should drop references to unused
abstracts but wasn't, resulting in each collection decrementing the
count by one until 0 was hit, even if other threads maintained a
reference.
This commit is contained in:
Calvin Rose 2023-08-20 14:50:46 -05:00
parent 5f5e5cf693
commit e5893d0692
2 changed files with 8 additions and 6 deletions

View File

@ -182,7 +182,7 @@ void janet_os_mutex_lock(JanetOSMutex *mutex) {
void janet_os_mutex_unlock(JanetOSMutex *mutex) { void janet_os_mutex_unlock(JanetOSMutex *mutex) {
int ret = pthread_mutex_unlock((pthread_mutex_t *) mutex); int ret = pthread_mutex_unlock((pthread_mutex_t *) mutex);
if (ret) janet_panic("cannot release lock"); if (ret) janet_panicf("cannot release lock: %s", strerror(ret));
} }
void janet_os_rwlock_init(JanetOSRWLock *rwlock) { void janet_os_rwlock_init(JanetOSRWLock *rwlock) {

View File

@ -364,20 +364,22 @@ void janet_sweep() {
/* If not visited... */ /* If not visited... */
if (!janet_truthy(items[i].value)) { if (!janet_truthy(items[i].value)) {
void *abst = janet_unwrap_abstract(items[i].key); void *abst = janet_unwrap_abstract(items[i].key);
if (0 == janet_abstract_decref(abst)) { if (0 == janet_abstract_decref(abst)) {
/* Run finalizer */ /* Run finalizer */
JanetAbstractHead *head = janet_abstract_head(abst); JanetAbstractHead *head = janet_abstract_head(abst);
if (head->type->gc) { if (head->type->gc) {
janet_assert(!head->type->gc(head->data, head->size), "finalizer failed"); janet_assert(!head->type->gc(head->data, head->size), "finalizer failed");
} }
/* Mark as tombstone in place */
items[i].key = janet_wrap_nil();
items[i].value = janet_wrap_false();
janet_vm.threaded_abstracts.deleted++;
janet_vm.threaded_abstracts.count--;
/* Free memory */ /* Free memory */
janet_free(janet_abstract_head(abst)); janet_free(janet_abstract_head(abst));
} }
/* Mark as tombstone in place */
items[i].key = janet_wrap_nil();
items[i].value = janet_wrap_false();
janet_vm.threaded_abstracts.deleted++;
janet_vm.threaded_abstracts.count--;
} }
/* Reset for next sweep */ /* Reset for next sweep */