summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--httpd.c81
-rw-r--r--main.c25
2 files changed, 100 insertions, 6 deletions
diff --git a/httpd.c b/httpd.c
index 14e9565..ecb64b4 100644
--- a/httpd.c
+++ b/httpd.c
@@ -22,13 +22,13 @@
22 22
23#include <sys/resource.h> // for getrlimit() 23#include <sys/resource.h> // for getrlimit()
24 24
25#include <sys/mman.h>
26
25#ifdef USE_POLL_FOR_SLEEP 27#ifdef USE_POLL_FOR_SLEEP
26#include <poll.h> 28#include <poll.h>
27#endif 29#endif
28 30
29/** server stat **/ 31/** server state **/
30
31srv_state s_state = {0};
32srv_state *p_state = NULL; 32srv_state *p_state = NULL;
33 33
34 34
@@ -622,6 +622,74 @@ void term_handler(int s)
622} 622}
623 623
624 624
625srv_state *srv_state_op(xs_str **fname, int op)
626/* opens or deletes the shared memory object */
627{
628 int fd;
629 srv_state *ss = NULL;
630
631 if (*fname == NULL)
632 *fname = xs_fmt("/%s_snac_state", xs_dict_get(srv_config, "host"));
633
634 switch (op) {
635 case 0: /* open for writing */
636 if ((fd = shm_open(*fname, O_CREAT | O_RDWR, 0666)) != -1) {
637 ftruncate(fd, sizeof(*ss));
638
639 if ((ss = mmap(0, sizeof(*ss), PROT_READ | PROT_WRITE,
640 MAP_SHARED, fd, 0)) == MAP_FAILED)
641 ss = NULL;
642
643 close(fd);
644 }
645
646 if (ss == NULL) {
647 /* shared memory error: just create a plain structure */
648 srv_log(xs_fmt("warning: shm object error (%s)", strerror(errno)));
649 ss = malloc(sizeof(*ss));
650 }
651
652 /* init structure */
653 *ss = (srv_state){0};
654 ss->s_size = sizeof(*ss);
655
656 break;
657
658 case 1: /* open for reading */
659 if ((fd = shm_open(*fname, O_RDONLY, 0666)) != -1) {
660 if ((ss = mmap(0, sizeof(*ss), PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)
661 ss = NULL;
662
663 close(fd);
664 }
665
666 if (ss == NULL) {
667 /* shared memory error */
668 srv_log(xs_fmt("error: shm object error (%s) server not running?", strerror(errno)));
669 }
670 else
671 if (ss->s_size != sizeof(*ss)) {
672 srv_log(xs_fmt("error: struct size mismatch (%d != %d)",
673 ss->s_size, sizeof(*ss)));
674
675 munmap(ss, sizeof(*ss));
676
677 ss = NULL;
678 }
679
680 break;
681
682 case 2: /* unlink */
683 if (*fname)
684 shm_unlink(*fname);
685
686 break;
687 }
688
689 return ss;
690}
691
692
625void httpd(void) 693void httpd(void)
626/* starts the server */ 694/* starts the server */
627{ 695{
@@ -631,12 +699,11 @@ void httpd(void)
631 pthread_t threads[MAX_THREADS] = {0}; 699 pthread_t threads[MAX_THREADS] = {0};
632 int n; 700 int n;
633 xs *sem_name = NULL; 701 xs *sem_name = NULL;
702 xs *shm_name = NULL;
634 sem_t anon_job_sem; 703 sem_t anon_job_sem;
635 704
636 /* setup the server stat structure */ 705 /* setup the server stat structure */
637 { 706 p_state = srv_state_op(&shm_name, 0);
638 p_state = &s_state;
639 }
640 707
641 p_state->srv_start_time = time(NULL); 708 p_state->srv_start_time = time(NULL);
642 709
@@ -736,6 +803,8 @@ void httpd(void)
736 sem_close(job_sem); 803 sem_close(job_sem);
737 sem_unlink(sem_name); 804 sem_unlink(sem_name);
738 805
806 srv_state_op(&shm_name, 2);
807
739 xs *uptime = xs_str_time_diff(time(NULL) - p_state->srv_start_time); 808 xs *uptime = xs_str_time_diff(time(NULL) - p_state->srv_start_time);
740 809
741 srv_log(xs_fmt("httpd%s stop %s:%s (run time: %s)", 810 srv_log(xs_fmt("httpd%s stop %s:%s (run time: %s)",
diff --git a/main.c b/main.c
index f5fb0e9..08f23d5 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,7 @@
4#include "xs.h" 4#include "xs.h"
5#include "xs_io.h" 5#include "xs_io.h"
6#include "xs_json.h" 6#include "xs_json.h"
7#include "xs_time.h"
7 8
8#include "snac.h" 9#include "snac.h"
9 10
@@ -22,6 +23,7 @@ int usage(void)
22 printf("deluser {basedir} {uid} Deletes a user\n"); 23 printf("deluser {basedir} {uid} Deletes a user\n");
23 printf("httpd {basedir} Starts the HTTPD daemon\n"); 24 printf("httpd {basedir} Starts the HTTPD daemon\n");
24 printf("purge {basedir} Purges old data\n"); 25 printf("purge {basedir} Purges old data\n");
26 printf("state {basedir} Prints server state\n");
25 printf("webfinger {basedir} {actor} Queries about an actor (@user@host or actor url)\n"); 27 printf("webfinger {basedir} {actor} Queries about an actor (@user@host or actor url)\n");
26 printf("queue {basedir} {uid} Processes a user queue\n"); 28 printf("queue {basedir} {uid} Processes a user queue\n");
27 printf("follow {basedir} {uid} {actor} Follows an actor\n"); 29 printf("follow {basedir} {uid} {actor} Follows an actor\n");
@@ -138,6 +140,29 @@ int main(int argc, char *argv[])
138 return 0; 140 return 0;
139 } 141 }
140 142
143 if (strcmp(cmd, "state") == 0) { /** **/
144 xs *shm_name = NULL;
145 srv_state *p_state = srv_state_op(&shm_name, 1);
146
147 if (p_state == NULL)
148 return 1;
149
150 srv_state ss = *p_state;
151 int n;
152
153 printf("server: %s (%s)\n", xs_dict_get(srv_config, "host"), USER_AGENT);
154 xs *uptime = xs_str_time_diff(time(NULL) - ss.srv_start_time);
155 printf("uptime: %s\n", uptime);
156 printf("job fifo size (cur): %d\n", ss.job_fifo_size);
157 printf("job fifo size (peak): %d\n", ss.peak_job_fifo_size);
158 char *th_states[] = { "stopped", "waiting", "input", "output" };
159
160 for (n = 0; n < ss.n_threads; n++)
161 printf("thread #%d state: %s\n", n, th_states[ss.th_state[n]]);
162
163 return 0;
164 }
165
141 if ((user = GET_ARGV()) == NULL) 166 if ((user = GET_ARGV()) == NULL)
142 return usage(); 167 return usage();
143 168