mirror of
https://github.com/janet-lang/janet
synced 2024-11-24 17:27:18 +00:00
Decrement thread channel pointer during cleanup without adding to heap.
This commit is contained in:
parent
c8827424e7
commit
1920ecd668
@ -598,14 +598,15 @@ static int janet_chan_pack(JanetChannel *chan, Janet *x) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int janet_chan_unpack(JanetChannel *chan, Janet *x) {
|
static int janet_chan_unpack(JanetChannel *chan, Janet *x, int is_cleanup) {
|
||||||
if (!janet_chan_is_threaded(chan)) return 0;
|
if (!janet_chan_is_threaded(chan)) return 0;
|
||||||
switch (janet_type(*x)) {
|
switch (janet_type(*x)) {
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
case JANET_BUFFER: {
|
case JANET_BUFFER: {
|
||||||
JanetBuffer *buf = janet_unwrap_buffer(*x);
|
JanetBuffer *buf = janet_unwrap_buffer(*x);
|
||||||
*x = janet_unmarshal(buf->data, buf->count, JANET_MARSHAL_UNSAFE, NULL, NULL);
|
int flags = is_cleanup ? JANET_MARSHAL_UNSAFE : (JANET_MARSHAL_UNSAFE | JANET_MARSHAL_DECREF);
|
||||||
|
*x = janet_unmarshal(buf->data, buf->count, flags, NULL, NULL);
|
||||||
janet_buffer_deinit(buf);
|
janet_buffer_deinit(buf);
|
||||||
janet_free(buf);
|
janet_free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
@ -639,7 +640,7 @@ static void janet_chan_deinit(JanetChannel *chan) {
|
|||||||
if (janet_chan_is_threaded(chan)) {
|
if (janet_chan_is_threaded(chan)) {
|
||||||
Janet item;
|
Janet item;
|
||||||
while (!janet_q_pop(&chan->items, &item, sizeof(item))) {
|
while (!janet_q_pop(&chan->items, &item, sizeof(item))) {
|
||||||
janet_chan_unpack(chan, &item);
|
janet_chan_unpack(chan, &item, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
janet_q_deinit(&chan->items);
|
janet_q_deinit(&chan->items);
|
||||||
@ -747,12 +748,12 @@ static void janet_thread_chan_cb(JanetEVGenericMessage msg) {
|
|||||||
janet_ev_dec_refcount();
|
janet_ev_dec_refcount();
|
||||||
if (fiber->sched_id == sched_id) {
|
if (fiber->sched_id == sched_id) {
|
||||||
if (mode == JANET_CP_MODE_CHOICE_READ) {
|
if (mode == JANET_CP_MODE_CHOICE_READ) {
|
||||||
janet_assert(!janet_chan_unpack(channel, &x), "packing error");
|
janet_assert(!janet_chan_unpack(channel, &x, 0), "packing error");
|
||||||
janet_schedule(fiber, make_read_result(channel, x));
|
janet_schedule(fiber, make_read_result(channel, x));
|
||||||
} else if (mode == JANET_CP_MODE_CHOICE_WRITE) {
|
} else if (mode == JANET_CP_MODE_CHOICE_WRITE) {
|
||||||
janet_schedule(fiber, make_write_result(channel));
|
janet_schedule(fiber, make_write_result(channel));
|
||||||
} else if (mode == JANET_CP_MODE_READ) {
|
} else if (mode == JANET_CP_MODE_READ) {
|
||||||
janet_assert(!janet_chan_unpack(channel, &x), "packing error");
|
janet_assert(!janet_chan_unpack(channel, &x, 0), "packing error");
|
||||||
janet_schedule(fiber, x);
|
janet_schedule(fiber, x);
|
||||||
} else if (mode == JANET_CP_MODE_WRITE) {
|
} else if (mode == JANET_CP_MODE_WRITE) {
|
||||||
janet_schedule(fiber, janet_wrap_channel(channel));
|
janet_schedule(fiber, janet_wrap_channel(channel));
|
||||||
@ -893,7 +894,7 @@ static int janet_channel_pop(JanetChannel *channel, Janet *item, int is_choice)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
janet_assert(!janet_chan_unpack(channel, item), "bad channel packing");
|
janet_assert(!janet_chan_unpack(channel, item, 0), "bad channel packing");
|
||||||
if (!janet_q_pop(&channel->write_pending, &writer, sizeof(writer))) {
|
if (!janet_q_pop(&channel->write_pending, &writer, sizeof(writer))) {
|
||||||
/* Pending writer */
|
/* Pending writer */
|
||||||
if (is_threaded) {
|
if (is_threaded) {
|
||||||
|
@ -1396,16 +1396,21 @@ static const uint8_t *unmarshal_one(
|
|||||||
} u;
|
} u;
|
||||||
memcpy(u.bytes, data, sizeof(void *));
|
memcpy(u.bytes, data, sizeof(void *));
|
||||||
data += sizeof(void *);
|
data += sizeof(void *);
|
||||||
*out = janet_wrap_abstract(u.ptr);
|
|
||||||
|
|
||||||
/* Check if we have already seen this abstract type - if we have, decrement refcount */
|
if (flags & JANET_MARSHAL_DECREF) {
|
||||||
Janet check = janet_table_get(&janet_vm.threaded_abstracts, *out);
|
/* Decrement immediately and don't bother putting into heap */
|
||||||
if (janet_checktype(check, JANET_NIL)) {
|
|
||||||
/* Transfers reference from threaded channel buffer to current heap */
|
|
||||||
janet_table_put(&janet_vm.threaded_abstracts, *out, janet_wrap_false());
|
|
||||||
} else {
|
|
||||||
/* Heap reference already accounted for, remove threaded channel reference. */
|
|
||||||
janet_abstract_decref(u.ptr);
|
janet_abstract_decref(u.ptr);
|
||||||
|
*out = janet_wrap_nil();
|
||||||
|
} else {
|
||||||
|
*out = janet_wrap_abstract(u.ptr);
|
||||||
|
Janet check = janet_table_get(&janet_vm.threaded_abstracts, *out);
|
||||||
|
if (janet_checktype(check, JANET_NIL)) {
|
||||||
|
/* Transfers reference from threaded channel buffer to current heap */
|
||||||
|
janet_table_put(&janet_vm.threaded_abstracts, *out, janet_wrap_false());
|
||||||
|
} else {
|
||||||
|
/* Heap reference already accounted for, remove threaded channel reference. */
|
||||||
|
janet_abstract_decref(u.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
janet_v_push(st->lookup, *out);
|
janet_v_push(st->lookup, *out);
|
||||||
@ -1419,7 +1424,6 @@ static const uint8_t *unmarshal_one(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef EXTRA
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Janet janet_unmarshal(
|
Janet janet_unmarshal(
|
||||||
|
@ -49,6 +49,8 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define JANET_MARSHAL_DECREF 0x40000
|
||||||
|
|
||||||
#define janet_assert(c, m) do { \
|
#define janet_assert(c, m) do { \
|
||||||
if (!(c)) JANET_EXIT((m)); \
|
if (!(c)) JANET_EXIT((m)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
Loading…
Reference in New Issue
Block a user