1
0
mirror of https://github.com/janet-lang/janet synced 2025-07-06 03:52:54 +00:00

Add ev/call.

This is a common operation, and making fibers manually can be tedious.
This commit is contained in:
Calvin Rose 2020-07-06 19:13:32 -05:00
parent 51cf6465ff
commit cd197e8be3
4 changed files with 34 additions and 25 deletions

View File

@ -1,27 +1,17 @@
(defn handler (defn handler
"Simple handler for connections." "Simple handler for connections."
[stream] [stream]
(def id (gensym)) (defer (:close stream)
(def b @"") (def id (gensym))
(print "Connection " id "!") (def b @"")
(while (:read stream 1024 b) (print "Connection " id "!")
(repeat 10 (print "work for " id " ...") (ev/sleep 1)) (while (:read stream 1024 b)
(:write stream b) (repeat 10 (print "work for " id " ...") (ev/sleep 1))
(buffer/clear b)) (:write stream b)
(printf "Done %v!" id)) (buffer/clear b))
(printf "Done %v!" id)))
(defn spawn-kid
"Run handler in a new fiber"
[conn]
(def f (fiber/new handler))
(ev/go f conn))
(print "Starting echo server on 127.0.0.1:8000")
(def server (net/server "127.0.0.1" "8000"))
# Run server. # Run server.
(while true (let [server (net/server "127.0.0.1" "8000")]
(with [conn (:accept server)] (print "Starting echo server on 127.0.0.1:8000")
(spawn-kid conn) (while true (ev/call handler (:accept server))))
(ev/sleep 0.1)))

View File

@ -516,6 +516,11 @@
(with-syms [iter] (with-syms [iter]
~(do (var ,iter ,n) (while (> ,iter 0) ,;body (-- ,iter))))) ~(do (var ,iter ,n) (while (> ,iter 0) ,;body (-- ,iter)))))
(defmacro forever
"Evaluate body repeatedly forever, or until a break statement at the top level."
[& body]
~(while true ,;body))
(defmacro each (defmacro each
"Loop over each value in ds. Returns nil." "Loop over each value in ds. Returns nil."
[x ds & body] [x ds & body]

View File

@ -517,7 +517,7 @@ void janet_ev_deinit(void) {
/* C functions */ /* C functions */
static Janet cfun_ev_spawn(int32_t argc, Janet *argv) { static Janet cfun_ev_go(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2); janet_arity(argc, 1, 2);
JanetFiber *fiber = janet_getfiber(argv, 0); JanetFiber *fiber = janet_getfiber(argv, 0);
Janet value = argc == 2 ? argv[1] : janet_wrap_nil(); Janet value = argc == 2 ? argv[1] : janet_wrap_nil();
@ -525,6 +525,14 @@ static Janet cfun_ev_spawn(int32_t argc, Janet *argv) {
return argv[0]; return argv[0];
} }
static Janet cfun_ev_call(int32_t argc, Janet *argv) {
janet_arity(argc, 1, -1);
JanetFunction *fn = janet_getfunction(argv, 0);
JanetFiber *fiber = janet_fiber(fn, 64, argc - 1, argv + 1);
janet_schedule(fiber, janet_wrap_nil());
return janet_wrap_fiber(fiber);
}
static Janet cfun_ev_sleep(int32_t argc, Janet *argv) { static Janet cfun_ev_sleep(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1); janet_fixarity(argc, 1);
double sec = janet_getnumber(argv, 0); double sec = janet_getnumber(argv, 0);
@ -537,7 +545,13 @@ static Janet cfun_ev_sleep(int32_t argc, Janet *argv) {
static const JanetReg ev_cfuns[] = { static const JanetReg ev_cfuns[] = {
{ {
"ev/go", cfun_ev_spawn, "ev/call", cfun_ev_call,
JDOC("(ev/call fn & args)\n\n"
"Call a function asynchronously. Returns a fiber that is scheduled to "
"run the function.")
},
{
"ev/go", cfun_ev_go,
JDOC("(ev/go fiber &opt value)\n\n" JDOC("(ev/go fiber &opt value)\n\n"
"Put a fiber on the event loop to be resumed later. Optionally pass " "Put a fiber on the event loop to be resumed later. Optionally pass "
"a value to resume with, otherwise resumes with nil.") "a value to resume with, otherwise resumes with nil.")

View File

@ -664,7 +664,7 @@ static void check_stream_flag(JanetStream *stream, int flag) {
if (flag == JANET_STREAM_WRITABLE) msg = "writable"; if (flag == JANET_STREAM_WRITABLE) msg = "writable";
if (flag == JANET_STREAM_ACCEPTABLE) msg = "server"; if (flag == JANET_STREAM_ACCEPTABLE) msg = "server";
if (flag == JANET_STREAM_UDPSERVER) msg = "datagram server"; if (flag == JANET_STREAM_UDPSERVER) msg = "datagram server";
janet_panicf("bad stream - expected %s stream", msg); janet_panicf("bad stream, expected %s stream", msg);
} }
} }