Allow passing a function to directly to ev/go.

Makes ev/call less useful but ev/go more useful. No need
to construct as many identical intermediate fibers.
This commit is contained in:
Calvin Rose 2021-08-30 22:22:22 -05:00
parent bb1331e449
commit 5464a7a379
3 changed files with 39 additions and 7 deletions

View File

@ -10,3 +10,13 @@
(ev/call worker :b 5)
(ev/sleep 0.3)
(ev/call worker :c 12)
(defn worker2
[name]
(repeat 10
(ev/sleep 0.2)
(print name " working")))
(ev/go worker2 :bob)
(ev/go worker2 :joe)
(ev/go worker2 :sally)

View File

@ -3360,23 +3360,23 @@
Returns a fiber that is scheduled to run the function.
```
[f & args]
(ev/go (fiber/new (fn [&] (f ;args)) :tp)))
(ev/go (fn _call [&] (f ;args))))
(defmacro ev/spawn
"Run some code in a new fiber. This is shorthand for (ev/call (fn [] ;body))."
[& body]
~(,ev/go (fiber/new (fn _spawn [&] ,;body) :tp)))
~(,ev/go (fn _spawn [&] ,;body)))
(defmacro ev/do-thread
``Run some code in a new thread. Suspends the current fiber until the thread is complete, and
evaluates to nil.``
[& body]
~(,ev/thread (fiber/new (fn _thread [&] ,;body) :t)))
~(,ev/thread (fn _do-thread [&] ,;body)))
(defmacro ev/spawn-thread
``Run some code in a new thread. Like `ev/do-thread`, but returns nil immediately.``
[& body]
~(,ev/thread (fiber/new (fn _thread [&] ,;body) :t) nil :n))
~(,ev/thread (fn _spawn-thread [&] ,;body) nil :n))
(defmacro ev/with-deadline
`Run a body of code with a deadline, such that if the code does not complete before
@ -3407,7 +3407,7 @@
(def ,res @[])
(,wait-for-fibers ,chan
,(seq [[i body] :pairs bodies]
~(,ev/go (,fiber/new (fn [] (put ,res ,i ,body)) :tp) nil ,chan)))
~(,ev/go (fn [] (put ,res ,i ,body)) nil ,chan)))
,res))))
(compwhen (dyn 'net/listen)

View File

@ -2443,12 +2443,34 @@ JANET_CORE_FN(cfun_ev_go,
"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.") {
janet_arity(argc, 1, 3);
JanetFiber *fiber = janet_getfiber(argv, 0);
Janet value = argc >= 2 ? argv[1] : janet_wrap_nil();
void *supervisor = janet_optabstract(argv, argc, 2, &janet_channel_type, janet_vm.root_fiber->supervisor_channel);
JanetFiber *fiber;
if (janet_checktype(argv[0], JANET_FUNCTION)) {
/* Create a fiber for the user */
JanetFunction *func = janet_unwrap_function(argv[0]);
if (func->def->min_arity > 1) {
janet_panicf("task function must accept 0 or 1 arguments");
}
fiber = janet_fiber(func, 64, func->def->min_arity, &value);
fiber->flags |=
JANET_FIBER_MASK_ERROR |
JANET_FIBER_MASK_USER0 |
JANET_FIBER_MASK_USER1 |
JANET_FIBER_MASK_USER2 |
JANET_FIBER_MASK_USER3 |
JANET_FIBER_MASK_USER4;
if (!janet_vm.fiber->env) {
janet_vm.fiber->env = janet_table(0);
}
fiber->env = janet_table(0);
fiber->env->proto = janet_vm.fiber->env;
} else {
fiber = janet_getfiber(argv, 0);
}
fiber->supervisor_channel = supervisor;
janet_schedule(fiber, value);
return argv[0];
return janet_wrap_fiber(fiber);
}
/* For ev/thread - Run an interpreter in the new thread. */