1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-28 19:19:53 +00:00

Add net/listen and net/accept-loop.

These are the elements that make up net/server, which has been moved
into pure Janet instead.
This commit is contained in:
Calvin Rose 2020-11-09 11:18:09 -06:00
parent 099a912992
commit 6f1d5d3b73
2 changed files with 49 additions and 28 deletions

View File

@ -2722,6 +2722,28 @@
:on-status (or onsignal (make-onsignal env 1)) :on-status (or onsignal (make-onsignal env 1))
:source "repl"})) :source "repl"}))
###
###
### Extras
###
###
(defmacro- guarddef
[sym form]
(if (dyn sym)
form))
(guarddef net/listen
(defn net/server
"Start a server asynchornously with net/listen and net/accept-loop. Returns the new server stream."
[host port &opt handler type]
(def s (net/listen host port type))
(if handler
(ev/go (fn [] (net/accept-loop s handler))))
s))
(undef guarddef)
### ###
### ###
### CLI Tool Main ### CLI Tool Main

View File

@ -856,13 +856,11 @@ static const char *serverify_socket(JSock sfd) {
return NULL; return NULL;
} }
static Janet cfun_net_server(int32_t argc, Janet *argv) { static Janet cfun_net_listen(int32_t argc, Janet *argv) {
janet_arity(argc, 2, 4); janet_arity(argc, 2, 3);
/* Get host, port, and handler*/ /* Get host, port, and handler*/
JanetFunction *fun = janet_optfunction(argv, argc, 2, NULL); int socktype = janet_get_sockettype(argv, argc, 2);
int socktype = janet_get_sockettype(argv, argc, 3);
int is_unix = 0; int is_unix = 0;
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 1, &is_unix); struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 1, &is_unix);
@ -912,15 +910,8 @@ static Janet cfun_net_server(int32_t argc, Janet *argv) {
if (socktype == SOCK_DGRAM) { if (socktype == SOCK_DGRAM) {
/* Datagram server (UDP) */ /* Datagram server (UDP) */
if (NULL == fun) {
/* Server no handler */
JanetStream *stream = make_stream(sfd, JANET_STREAM_UDPSERVER | JANET_STREAM_READABLE); JanetStream *stream = make_stream(sfd, JANET_STREAM_UDPSERVER | JANET_STREAM_READABLE);
return janet_wrap_abstract(stream); return janet_wrap_abstract(stream);
} else {
/* Server with handler */
janet_panic("handler must be nil for datagram server");
}
} else { } else {
/* Stream server (TCP) */ /* Stream server (TCP) */
@ -932,14 +923,8 @@ static Janet cfun_net_server(int32_t argc, Janet *argv) {
} }
/* Put sfd on our loop */ /* Put sfd on our loop */
if (NULL == fun) {
JanetStream *stream = make_stream(sfd, JANET_STREAM_ACCEPTABLE); JanetStream *stream = make_stream(sfd, JANET_STREAM_ACCEPTABLE);
return janet_wrap_abstract(stream); return janet_wrap_abstract(stream);
} else {
/* Server with handler */
JanetStream *stream = make_stream(sfd, JANET_STREAM_ACCEPTABLE);
janet_sched_accept(stream, fun);
}
} }
} }
@ -954,6 +939,14 @@ static void check_stream_flag(JanetStream *stream, int flag) {
} }
} }
static Janet cfun_stream_accept_loop(int32_t argc, Janet *argv) {
janet_fixarity(argc, 2);
JanetStream *stream = janet_getabstract(argv, 0, &StreamAT);
check_stream_flag(stream, JANET_STREAM_ACCEPTABLE);
JanetFunction *fun = janet_getfunction(argv, 1);
janet_sched_accept(stream, fun);
}
static Janet cfun_stream_accept(int32_t argc, Janet *argv) { static Janet cfun_stream_accept(int32_t argc, Janet *argv) {
janet_arity(argc, 1, 2); janet_arity(argc, 1, 2);
JanetStream *stream = janet_getabstract(argv, 0, &StreamAT); JanetStream *stream = janet_getabstract(argv, 0, &StreamAT);
@ -1060,6 +1053,7 @@ static const JanetMethod stream_methods[] = {
{"write", cfun_stream_write}, {"write", cfun_stream_write},
{"flush", cfun_stream_flush}, {"flush", cfun_stream_flush},
{"accept", cfun_stream_accept}, {"accept", cfun_stream_accept},
{"accept-loop", cfun_stream_accept_loop},
{"send-to", cfun_stream_send_to}, {"send-to", cfun_stream_send_to},
{"recv-from", cfun_stream_recv_from}, {"recv-from", cfun_stream_recv_from},
{NULL, NULL} {NULL, NULL}
@ -1082,12 +1076,11 @@ static const JanetReg net_cfuns[] = {
"unix domain sockets are specified with a leading '@' character in port.") "unix domain sockets are specified with a leading '@' character in port.")
}, },
{ {
"net/server", cfun_net_server, "net/listen", cfun_net_listen,
JDOC("(net/server host port &opt handler type)\n\n" JDOC("(net/listen host port &opt type)\n\n"
"Start a TCP server. handler is a function that will be called with a stream " "Creates a server. Returns a new stream that is neither readable nor "
"on each connection to the server. Returns a new stream that is neither readable nor " "writeable. Use net/accept or net/accept-loop be to handle connections and start the server."
"writeable. If handler is nil or not provided, net/accept must be used to get the next connection " "The type parameter specifies the type of network connection, either "
"to the server. The type parameter specifies the type of network connection, either "
"a :stream (usually tcp), or :datagram (usually udp). If not specified, the default is " "a :stream (usually tcp), or :datagram (usually udp). If not specified, the default is "
":stream. The host and port arguments are the same as in net/address.") ":stream. The host and port arguments are the same as in net/address.")
}, },
@ -1098,6 +1091,12 @@ static const JanetReg net_cfuns[] = {
"Takes an optional timeout in seconds, after which will return nil. " "Takes an optional timeout in seconds, after which will return nil. "
"Returns a new duplex stream which represents a connection to the client.") "Returns a new duplex stream which represents a connection to the client.")
}, },
{
"net/accept-loop", cfun_stream_accept_loop,
JDOC("(net/accept-loop stream handler)\n\n"
"Shorthand for running a server stream that will continuously accept new connections."
"Blocks the current fiber until the stream is closed, and will return the stream.")
},
{ {
"net/read", cfun_stream_read, "net/read", cfun_stream_read,
JDOC("(net/read stream nbytes &opt buf timeout)\n\n" JDOC("(net/read stream nbytes &opt buf timeout)\n\n"