diff options
author | Leah Neukirchen <leah@vuxu.org> | 2022-01-06 22:26:21 +0100 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2022-01-06 22:26:21 +0100 |
commit | e86cc66cc9798a506dda02cf39126caff696d456 (patch) | |
tree | 96f7281ff4860a36988dc1d8831063e041964e07 | |
parent | 7438111c1d6e05df06748a9aa43fe9c4cf065131 (diff) | |
download | rvnit-e86cc66cc9798a506dda02cf39126caff696d456.tar.gz rvnit-e86cc66cc9798a506dda02cf39126caff696d456.tar.xz rvnit-e86cc66cc9798a506dda02cf39126caff696d456.zip |
use lock for services access
This makes some continue statements ugly. :(
-rw-r--r-- | rvnit.c | 97 |
1 files changed, 73 insertions, 24 deletions
diff --git a/rvnit.c b/rvnit.c index 8f7ac73..1c5d352 100644 --- a/rvnit.c +++ b/rvnit.c @@ -43,6 +43,8 @@ struct entry { }; struct entry services[MAX_SV]; +pthread_mutex_t services_lock; + int level; pthread_t main_thread; @@ -225,6 +227,7 @@ socket_loop(void* ignored) if (cmd == 's') { time_t now = time(0); + pthread_mutex_lock(&services_lock); for (int i = 0; i < MAX_SV; i++) { if (services[i].name[2] == 'D' || services[i].name[2] == 'L') @@ -235,12 +238,14 @@ socket_loop(void* ignored) services[i].pid > 0 ? (long)(now - services[i].start) : 0, services[i].status); } + pthread_mutex_unlock(&services_lock); } if ((cmd == 'd' || cmd == 'u' || charsig(cmd)) && rd > 1) { buf[rd] = 0; printf("got %c|%s|\n", cmd, buf+1); + pthread_mutex_lock(&services_lock); for (int i = 0; i < MAX_SV; i++) { if (strcmp(services[i].name, buf+1) == 0) { if (cmd == 'd') { @@ -261,6 +266,7 @@ socket_loop(void* ignored) } } } + pthread_mutex_unlock(&services_lock); } if (cmd == 'r') { @@ -302,6 +308,7 @@ logger_loop(void* ignored) fds[nfds].events = POLLIN; nfds++; + pthread_mutex_lock(&services_lock); for (int i = 0; i < MAX_SV; i++) { if (!services[i].logged && services[i].logfd[0] > 0) { fds[nfds].fd = services[i].logfd[0]; @@ -309,6 +316,7 @@ logger_loop(void* ignored) nfds++; } } + pthread_mutex_unlock(&services_lock); int n = poll(fds, nfds, -1); if (n < 0) { @@ -348,6 +356,24 @@ logger_loop(void* ignored) continue; } + const char *sv = "<unknown>"; + long pid = -1; + + if (fds[j].fd == selflogfd[0]) { + sv = "rvnit"; + pid = getpid(); + } else { + pthread_mutex_lock(&services_lock); + for (int i = 0; i < MAX_SV; i++) { + if (services[i].logfd[0] == fds[j].fd) { + sv = services[i].name; + pid = services[i].display_pid; + break; + } + } + pthread_mutex_unlock(&services_lock); + } + char *s = buf; char *e = buf + rd; while (s < e) { @@ -355,22 +381,6 @@ logger_loop(void* ignored) if (!eol) eol = e; - const char *sv = "<unknown>"; - long pid = -1; - - if (fds[j].fd == selflogfd[0]) { - sv = "rvnit"; - pid = getpid(); - } else { - for (int i = 0; i < MAX_SV; i++) { - if (services[i].logfd[0] == fds[j].fd) { - sv = services[i].name; - pid = services[i].display_pid; - break; - } - } - } - printf("%s.%05ld %s[%ld]: %.*s\n", timestamp, now.tv_nsec / 10000, sv, pid, (int)(eol - s), s); @@ -546,6 +556,11 @@ main() fcntl(newlogfd[0], F_SETFD, FD_CLOEXEC); fcntl(newlogfd[1], F_SETFD, FD_CLOEXEC); + if (pthread_mutex_init(&services_lock, 0) != 0) { + perror("pthread_mutex_init"); + return 111; + } + main_thread = pthread_self(); /* block all signals in the threads */ @@ -561,7 +576,9 @@ main() return 111; } + pthread_mutex_lock(&services_lock); rescandir(); + pthread_mutex_unlock(&services_lock); LOG("booting"); @@ -570,6 +587,8 @@ main() /* spawn all of level */ int oneshot = 0; + pthread_mutex_lock(&services_lock); + // spawn loggers first for (i = 0; i < MAX_SV; i++) { if (services[i].level != level) @@ -598,6 +617,8 @@ main() } } + pthread_mutex_unlock(&services_lock); + while (oneshot) { int status = 0; int pid = wait(&status); @@ -605,12 +626,14 @@ main() if (pid < 0 && errno == ECHILD) break; + pthread_mutex_lock(&services_lock); + int i = reap(pid, status); if (i < 0) - continue; + goto cont1; if (services[i].level != level) - continue; + goto cont1; if (services[i].name[2] == 'S') { @@ -620,7 +643,7 @@ main() int r = on_error(); if (r == 0) { restart(i); - continue; + goto cont1; } if (r < 0) { LOG("no error handler, going on"); } if (r > 0) { @@ -634,6 +657,9 @@ main() services[i].name[2] == 'L') { restart(i); } + +cont1: + pthread_mutex_unlock(&services_lock); } } @@ -651,12 +677,15 @@ main() break; if (want_rescandir) { + pthread_mutex_lock(&services_lock); rescandir(); + pthread_mutex_unlock(&services_lock); want_rescandir = 0; } if (want_rescan) { printf("rescanning state\n"); + pthread_mutex_lock(&services_lock); for (i = 0; i < MAX_SV; i++) { if (services[i].name[2] == 'L') { if (services[i].state == UP && @@ -675,6 +704,7 @@ main() kill(services[i].pid, SIGTERM); } } + pthread_mutex_unlock(&services_lock); want_rescan = 0; } @@ -690,9 +720,11 @@ main() continue; } + pthread_mutex_lock(&services_lock); + int i = reap(pid, status); if (i < 0) - continue; + goto cont2; if (services[i].name[2] == 'D' || services[i].name[2] == 'L') { @@ -702,6 +734,9 @@ main() restart(i); } } + +cont2: + pthread_mutex_unlock(&services_lock); } LOG("shutting down"); @@ -714,6 +749,7 @@ fatal: ; // arrives with level < 99 int daemons = 0; int loggers = 0; + pthread_mutex_lock(&services_lock); for (i = 0; i < MAX_SV; i++) { if (services[i].level != level) continue; @@ -738,6 +774,7 @@ fatal: ; // arrives with level < 99 services[i].state = DOWN; } } + pthread_mutex_unlock(&services_lock); while (oneshot) { int status = 0; @@ -746,12 +783,14 @@ fatal: ; // arrives with level < 99 if (pid < 0 && errno == ECHILD) break; + pthread_mutex_lock(&services_lock); + int i = reap(pid, status); if (i < 0) - continue; + goto cont3; if (services[i].level != level) - continue; + goto cont3; if (services[i].name[2] == 'K') { LOG("oneshot %s exited with status %d", services[i].name, services[i].status); @@ -765,6 +804,9 @@ fatal: ; // arrives with level < 99 LOG("logger %s exited with status %d", services[i].name, services[i].status); loggers--; } + +cont3: + pthread_mutex_unlock(&services_lock); } // only daemons are left, wait up to 7s before sending @@ -780,6 +822,7 @@ fatal: ; // arrives with level < 99 if (slayed) break; LOG("slaying level=%d", level); + pthread_mutex_lock(&services_lock); for (i = 0; i < MAX_SV; i++) { if (services[i].level != level) continue; @@ -788,6 +831,7 @@ fatal: ; // arrives with level < 99 kill(services[i].pid, SIGCONT); } } + pthread_mutex_unlock(&services_lock); slayed = 1; continue; } @@ -795,12 +839,14 @@ fatal: ; // arrives with level < 99 if (pid < 0 && errno == ECHILD) break; + pthread_mutex_lock(&services_lock); + int i = reap(pid, status); if (i < 0) - continue; + goto cont4; if (services[i].level != level) - continue; + goto cont4; if (services[i].name[2] == 'K') { // can't happen @@ -815,6 +861,9 @@ fatal: ; // arrives with level < 99 LOG("logger %s exited with status %d", services[i].name, services[i].status); loggers--; } + +cont4: + pthread_mutex_unlock(&services_lock); } if (daemons) { |