shithub: mc

Download patch

ref: dd8235ce6d9c45e7039a821bdc86818c63c2823d
parent: d09137d7087bb2909f1e8ee02a098c44e42958ab
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Sep 10 17:38:47 EDT 2017

Refcount the HTTP server.

--- a/lib/http/server.myr
+++ b/lib/http/server.myr
@@ -25,18 +25,24 @@
 	| `std.Err e:	-> `std.Err `Econn
 	| `std.Ok lfd:
 		std.close(afd)
-		-> `std.Ok std.mk([.lfd=lfd])
+		-> `std.Ok std.mk([
+			.refs=1,
+			.lfd=lfd,
+			.quit=false
+		])
 	;;
 }
 
 const serve = {srv, fn
-	while true
+	while !srv.quit
 		match waitconn(srv)
-		| `std.Ok fd:	
+		| `std.Ok fd:
+			ref(srv)
 			thread.spawn({;communicate(srv, fd, fn)})
 		| `std.Err e:	/* eh? */
 		;;
 	;;
+	unref(srv)
 }
 
 const communicate = {srv, fd, fn
@@ -50,6 +56,7 @@
 		;;
 	;;
 	std.close(fd)
+	unref(srv)
 }
 
 const respond = {srv, s, resp
@@ -78,6 +85,8 @@
 
 const shutdown = {srv
 	std.close(srv.lfd)
+	srv.quit = true
+
 }
 
 
@@ -88,3 +97,14 @@
 	;;
 }
 
+
+const ref = {srv
+	thread.xadd(&srv.refs, 1)
+}
+
+const unref = {srv
+	thread.xadd(&srv.refs, -1)
+	if thread.xget(&srv.refs) == 0
+		std.free(srv)
+	;;
+}
--- a/lib/http/srvdot.myr
+++ b/lib/http/srvdot.myr
@@ -28,6 +28,7 @@
 	std.put("Reading path {}\n", req.url.path)
 	match req.url.path
 	| "/ping":	respond(srv, sess, 200, "pong")
+	| "/quit":	http.shutdown(srv)
 	| fspath:	showfile(srv, sess, req.url.path)
 	;;
 }
--- a/lib/http/types.myr
+++ b/lib/http/types.myr
@@ -16,6 +16,7 @@
 
 	type server = struct
 		lfd	: std.fd
+		refs	: uint32
 		quit	: bool
 	;;