diff options
| -rw-r--r-- | httpd.c | 81 | ||||
| -rw-r--r-- | main.c | 25 |
2 files changed, 100 insertions, 6 deletions
| @@ -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 | |||
| 31 | srv_state s_state = {0}; | ||
| 32 | srv_state *p_state = NULL; | 32 | srv_state *p_state = NULL; |
| 33 | 33 | ||
| 34 | 34 | ||
| @@ -622,6 +622,74 @@ void term_handler(int s) | |||
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | 624 | ||
| 625 | srv_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 | |||
| 625 | void httpd(void) | 693 | void 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)", |
| @@ -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 | ||