uvserver
This commit is contained in:
parent
cd051dc8c0
commit
f191915dbf
|
@ -1,2 +1,3 @@
|
||||||
compiled/
|
compiled/
|
||||||
echoserver.beam
|
echoserver.beam
|
||||||
|
uvserver
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -1,5 +1,9 @@
|
||||||
all:
|
all: uvserver
|
||||||
raco make *.rkt
|
raco make *.rkt
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf compiled
|
rm -rf compiled
|
||||||
|
rm -f uvserver
|
||||||
|
|
||||||
|
uvserver: uvserver.c
|
||||||
|
gcc -o $@ $< -luv
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
(set! max-waypoint (string->number n))]
|
(set! max-waypoint (string->number n))]
|
||||||
#:once-any
|
#:once-any
|
||||||
["--erlang" "use erlang server" (set! server-variation 'erlang)]
|
["--erlang" "use erlang server" (set! server-variation 'erlang)]
|
||||||
|
["--uv" "use libuv server" (set! server-variation 'uv)]
|
||||||
["--minimart" "use minimart server" (set! server-variation 'minimart)]
|
["--minimart" "use minimart server" (set! server-variation 'minimart)]
|
||||||
["--other" name "use other server" (set! server-variation name)])
|
["--other" name "use other server" (set! server-variation name)])
|
||||||
|
|
||||||
|
@ -40,6 +41,9 @@
|
||||||
command))
|
command))
|
||||||
control)
|
control)
|
||||||
|
|
||||||
|
(define (capture-output command)
|
||||||
|
(string-trim (with-output-to-string (lambda () (system command)))))
|
||||||
|
|
||||||
(log-info "Starting server...")
|
(log-info "Starting server...")
|
||||||
(define server-control
|
(define server-control
|
||||||
(start-bg
|
(start-bg
|
||||||
|
@ -53,9 +57,11 @@
|
||||||
"erl -noshell -eval 'io:format(erlang:system_info(otp_release)), halt().'")
|
"erl -noshell -eval 'io:format(erlang:system_info(otp_release)), halt().'")
|
||||||
(write-logbook-datum! Tmachine
|
(write-logbook-datum! Tmachine
|
||||||
#:label "erlang-version"
|
#:label "erlang-version"
|
||||||
(string-trim (with-output-to-string
|
(capture-output erlang-version-command))
|
||||||
(lambda () (system erlang-version-command)))))
|
|
||||||
"./run-erlang-server.sh"]
|
"./run-erlang-server.sh"]
|
||||||
|
['uv
|
||||||
|
(write-logbook-datum! Tmachine #:label "uv-banner" (capture-output "./uvserver -v"))
|
||||||
|
"./uvserver"]
|
||||||
[(? string? other)
|
[(? string? other)
|
||||||
(printf "Please start the other server on hostname '~a' now.\n" server-hostname)
|
(printf "Please start the other server on hostname '~a' now.\n" server-hostname)
|
||||||
(printf "Press enter when it has started.\n")
|
(printf "Press enter when it has started.\n")
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
static int connection_count = 0;
|
||||||
|
|
||||||
|
static uv_buf_t alloc_buffer(uv_handle_t *handle, size_t suggested_size) {
|
||||||
|
return uv_buf_init(calloc(1, suggested_size), suggested_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_write_complete(uv_write_t *req, int status) {
|
||||||
|
/* we could check status here, but we don't care; just free, and be done */
|
||||||
|
free(req->data);
|
||||||
|
free(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_input(uv_stream_t *conn, ssize_t nread, uv_buf_t buf) {
|
||||||
|
if (nread == -1) {
|
||||||
|
/* here we could check uv_last_error(conn->loop).code to see whether it's UV_EOF or not */
|
||||||
|
/* but we don't care; just close, and be done */
|
||||||
|
connection_count--;
|
||||||
|
if (connection_count == 0) {
|
||||||
|
uv_stop(conn->loop);
|
||||||
|
}
|
||||||
|
uv_close((uv_handle_t *) conn, NULL);
|
||||||
|
} else {
|
||||||
|
uv_write_t *req = calloc(1, sizeof(uv_write_t));
|
||||||
|
/* we just echo what came in. */
|
||||||
|
req->data = buf.base;
|
||||||
|
buf.len = nread;
|
||||||
|
uv_write(req, conn, &buf, 1, on_write_complete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_connection(uv_stream_t *serversock, int status) {
|
||||||
|
uv_tcp_t *conn;
|
||||||
|
|
||||||
|
if (status == -1) {
|
||||||
|
/* error? */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = calloc(1, sizeof(uv_tcp_t));
|
||||||
|
uv_tcp_init(serversock->loop, conn);
|
||||||
|
if (uv_accept(serversock, (uv_stream_t *) conn) == 0) {
|
||||||
|
connection_count++;
|
||||||
|
uv_read_start((uv_stream_t *) conn, alloc_buffer, on_input);
|
||||||
|
} else {
|
||||||
|
uv_close((uv_handle_t *) conn, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int const PORTNUMBER = 5999;
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[]) {
|
||||||
|
uv_loop_t *uv = uv_default_loop();
|
||||||
|
uv_tcp_t serversock;
|
||||||
|
struct sockaddr_in bind_addr;
|
||||||
|
|
||||||
|
printf("uvserver; libuv version %s\n", uv_version_string());
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Accepting connections on port %d.\n", PORTNUMBER);
|
||||||
|
uv_tcp_init(uv, &serversock);
|
||||||
|
bind_addr = uv_ip4_addr("0.0.0.0", PORTNUMBER);
|
||||||
|
uv_tcp_bind(&serversock, bind_addr);
|
||||||
|
uv_listen((uv_stream_t *) &serversock, 4, on_connection);
|
||||||
|
|
||||||
|
uv_run(uv, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
uv_loop_delete(uv);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue