summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2023-10-21 18:51:38 +0200
committerLeah Neukirchen <leah@vuxu.org>2023-10-21 18:51:38 +0200
commitce5a3ad8a4199ed421b50c2fe506648700c82e11 (patch)
tree3ea3eb6599a095c0432e789f83c7944de9a34074
parent56e9eedfba7b68c925a5d0563b0e86d3fcb7f189 (diff)
downloadnitro-old-libuv.tar.gz
nitro-old-libuv.tar.xz
nitro-old-libuv.zip
add global shutdown old-libuv
-rw-r--r--nitro.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/nitro.c b/nitro.c
index d8ccadc..e3ac580 100644
--- a/nitro.c
+++ b/nitro.c
@@ -14,6 +14,12 @@
 uv_loop_t *loop;
 int controlsock;
 
+enum global_state {
+	GLBL_UP,
+	GLBL_WANT_SHUTDOWN,
+	GLBL_WANT_REBOOT,
+} global_state;
+
 enum process_state {
 	PROC_STOPPED = 1,
 	PROC_STARTING,
@@ -214,10 +220,12 @@ proc_cleanup(struct process *p)
 void
 process_step(struct process *p, enum process_events ev)
 {
-	printf("%d[%d] got %d\n", p->state, p->main.pid, ev);
+	printf("%d[%d] got %d %d\n", p->state, p->main.pid, ev, global_state);
 
 	switch (ev) {
 	case EVNT_WANT_UP:
+		if (global_state != GLBL_UP)
+			break;
 		switch (p->state) {
 		case PROC_STARTING:
 		case PROC_UP:
@@ -259,6 +267,8 @@ process_step(struct process *p, enum process_events ev)
 		break;
 
 	case EVNT_WANT_RESTART:
+		if (global_state != GLBL_UP)
+			break;
 		switch (p->state) {
 		case PROC_STARTING:
 		case PROC_UP:
@@ -336,15 +346,25 @@ process_step(struct process *p, enum process_events ev)
 			break;
 		}
 		break;
-
 	}
 }
 
 void
+do_shutdown(int state)
+{
+	global_state = state;
+	for (struct process *p = process_head; p; p = p->next)
+		process_step(p, EVNT_WANT_DOWN);
+}
+
+void
 callback_signal(uv_signal_t *handle, int signum)
 {
 	switch (signum) {
 	case SIGINT:
+		do_shutdown(GLBL_WANT_SHUTDOWN);
+		break;
+
 	case SIGTERM:
 		uv_signal_stop(handle);
 		uv_stop(loop);
@@ -515,6 +535,12 @@ callback_control_socket(uv_poll_t *handle, int status, int events)
 		}
 		goto fail;
 	}
+	case 'S':
+		do_shutdown(GLBL_WANT_SHUTDOWN);
+		goto ok;
+	case 'R':
+		do_shutdown(GLBL_WANT_REBOOT);
+		goto ok;
 	default:
 		if (charsig(buf[0])) {
 			struct process *p = find_service(buf + 1);
@@ -557,6 +583,25 @@ load_services()
 	closedir(dir);
 }
 
+void callback_stop_check(uv_check_t *handle)
+{
+	if (global_state == GLBL_UP)
+		return;
+
+	int up = 0;
+	for (struct process *p = process_head; p; p = p->next) {
+		printf("DBG %s %d %d\n", p->name, p->main.pid, p->state);
+		if (!(p->state == PROC_STOPPED || p->state == PROC_FATAL))
+			up++;
+	}
+	if (up) {
+		printf("shutdown waiting for %d processes\n", up);
+		return;
+	}
+
+	uv_stop(loop);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -602,6 +647,8 @@ main(int argc, char *argv[])
 	uv_pipe_open(&log_input, globallogfd[1]);
 	uv_read_start((uv_stream_t *)&log_pipe, fixed_log_buffer, read_log);
 
+	global_state = GLBL_UP;
+
 	load_services();
 
 	printf("nitro up at %d\n", getpid());
@@ -616,6 +663,10 @@ main(int argc, char *argv[])
 			process_step(p, EVNT_WANT_UP);
 	}
 
+	uv_check_t stop_check;
+	uv_check_init(loop, &stop_check);
+	uv_check_start(&stop_check, callback_stop_check);
+
 	uv_run(loop, UV_RUN_DEFAULT);
 
 	uv_loop_close(loop);