mirror of
https://github.com/janet-lang/janet
synced 2025-10-25 12:47:42 +00:00
Go back to a single supervisor channel per fiber.
We now also use the fiber mask to figure out which flags to wait for.
This commit is contained in:
@@ -507,24 +507,25 @@ void janet_ev_mark(void) {
|
||||
|
||||
static int janet_channel_push(JanetChannel *channel, Janet x, int mode);
|
||||
|
||||
static Janet make_supervisor_event(const char *name, JanetFiber *fiber) {
|
||||
Janet tup[2];
|
||||
tup[0] = janet_ckeywordv(name);
|
||||
tup[1] = janet_wrap_fiber(fiber);
|
||||
return janet_wrap_tuple(janet_tuple_n(tup, 2));
|
||||
}
|
||||
|
||||
/* Run a top level task */
|
||||
static void run_one(JanetFiber *fiber, Janet value, JanetSignal sigin) {
|
||||
fiber->flags &= ~JANET_FIBER_FLAG_SCHEDULED;
|
||||
Janet res;
|
||||
JanetSignal sig = janet_continue_signal(fiber, value, &res, sigin);
|
||||
if (sig != JANET_SIGNAL_EVENT && sig != JANET_SIGNAL_YIELD) {
|
||||
if (fiber->done_channel) {
|
||||
JanetChannel *chan = (JanetChannel *)(fiber->done_channel);
|
||||
janet_channel_push(chan, janet_wrap_fiber(fiber), 2);
|
||||
fiber->done_channel = NULL;
|
||||
fiber->event_channel = NULL;
|
||||
fiber->new_channel = NULL;
|
||||
} else if (sig != JANET_SIGNAL_OK) {
|
||||
JanetChannel *chan = (JanetChannel *)(fiber->supervisor_channel);
|
||||
if (NULL == chan) {
|
||||
if (sig != JANET_SIGNAL_EVENT && sig != JANET_SIGNAL_YIELD) {
|
||||
janet_stacktrace(fiber, res);
|
||||
}
|
||||
} else if (fiber->event_channel) {
|
||||
JanetChannel *chan = (JanetChannel *)(fiber->event_channel);
|
||||
janet_channel_push(chan, janet_wrap_fiber(fiber), 2);
|
||||
} else if (sig == JANET_SIGNAL_OK || (fiber->flags & (1 << sig))) {
|
||||
janet_channel_push(chan, make_supervisor_event(janet_signal_names[sig], fiber), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2001,25 +2002,21 @@ error:
|
||||
#endif
|
||||
}
|
||||
|
||||
static void janet_ev_go(JanetFiber *fiber, Janet value, JanetChannel *supervisor_channel) {
|
||||
fiber->supervisor_channel = supervisor_channel;
|
||||
/* janet_channel_push(supervisor_channel, make_supervisor_event("new", fiber), 2); */
|
||||
janet_schedule(fiber, value);
|
||||
}
|
||||
|
||||
/* C functions */
|
||||
|
||||
static Janet cfun_ev_go(int32_t argc, Janet *argv) {
|
||||
janet_arity(argc, 1, 5);
|
||||
janet_arity(argc, 1, 3);
|
||||
JanetFiber *fiber = janet_getfiber(argv, 0);
|
||||
Janet value = argc == 2 ? argv[1] : janet_wrap_nil();
|
||||
JanetChannel *done_channel = janet_optabstract(argv, argc, 2, &ChannelAT,
|
||||
janet_vm_root_fiber->done_channel);
|
||||
JanetChannel *new_channel = janet_optabstract(argv, argc, 3, &ChannelAT,
|
||||
janet_vm_root_fiber->new_channel);
|
||||
JanetChannel *event_channel = janet_optabstract(argv, argc, 4, &ChannelAT,
|
||||
janet_vm_root_fiber->event_channel);
|
||||
fiber->done_channel = done_channel;
|
||||
fiber->new_channel = new_channel;
|
||||
fiber->event_channel = event_channel;
|
||||
if (new_channel != NULL) {
|
||||
janet_channel_push((JanetChannel *) new_channel, janet_wrap_fiber(fiber), 2);
|
||||
}
|
||||
janet_schedule(fiber, value);
|
||||
JanetChannel *supervisor_channel = janet_optabstract(argv, argc, 2, &ChannelAT,
|
||||
janet_vm_root_fiber->supervisor_channel);
|
||||
janet_ev_go(fiber, value, supervisor_channel);
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
@@ -2030,13 +2027,7 @@ static Janet cfun_ev_call(int32_t argc, Janet *argv) {
|
||||
if (NULL == fiber) janet_panicf("invalid arity to function %v", argv[0]);
|
||||
fiber->env = janet_table(0);
|
||||
fiber->env->proto = janet_current_fiber()->env;
|
||||
fiber->done_channel = janet_vm_root_fiber->done_channel;
|
||||
fiber->event_channel = janet_vm_root_fiber->event_channel;
|
||||
fiber->new_channel = janet_vm_root_fiber->new_channel;
|
||||
if (fiber->new_channel != NULL) {
|
||||
janet_channel_push((JanetChannel *) fiber->new_channel, janet_wrap_fiber(fiber), 2);
|
||||
}
|
||||
janet_schedule(fiber, janet_wrap_nil());
|
||||
janet_ev_go(fiber, janet_wrap_nil(), (JanetChannel *)(janet_vm_root_fiber->supervisor_channel));
|
||||
return janet_wrap_fiber(fiber);
|
||||
}
|
||||
|
||||
@@ -2141,19 +2132,12 @@ static const JanetReg ev_cfuns[] = {
|
||||
},
|
||||
{
|
||||
"ev/go", cfun_ev_go,
|
||||
JDOC("(ev/go fiber &opt value done-chan new-chan event-chan)\n\n"
|
||||
JDOC("(ev/go fiber &opt value supervisor)\n\n"
|
||||
"Put a fiber on the event loop to be resumed later. Optionally pass "
|
||||
"a value to resume with, otherwise resumes with nil. Returns the fiber. "
|
||||
"\n\n"
|
||||
"Three optional `core/channel`s can be provided as well. These are channels "
|
||||
"that will the fiber will be pushed to with `ev/give` on the relevant event. "
|
||||
"\n\n"
|
||||
"* `done-chan` - when `fiber` completes or errors, it will be pushed to this channel.\n"
|
||||
"* `new-chan` - `fiber` will be pushed to this channel right away. Nested calls to `ev/go` "
|
||||
"that don't set `new-chan` will also push to this channel.\n"
|
||||
"* `event-chan` - when `fiber` yields to the event loop it will be pushed to this channel.\n\n"
|
||||
"With these channels, the programmer can implement a \"supervisor\" for fibers for a fault "
|
||||
"tolerant application.")
|
||||
"An optional `core/channel` can be provided as well as a supervisor. When various "
|
||||
"events occur in the newly scheduled fiber, an event will be pushed to the supervisor. "
|
||||
"If not provided, the new fiber will inherit the current supervisor.")
|
||||
},
|
||||
{
|
||||
"ev/sleep", cfun_ev_sleep,
|
||||
|
||||
Reference in New Issue
Block a user