summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.c40
-rw-r--r--httpd.c75
-rw-r--r--snac.h10
3 files changed, 69 insertions, 56 deletions
diff --git a/data.c b/data.c
index cd16341..e03a1ce 100644
--- a/data.c
+++ b/data.c
@@ -150,12 +150,12 @@ void user_free(snac *snac)
150} 150}
151 151
152 152
153int user_open(snac *snac, const char *uid) 153int user_open(snac *user, const char *uid)
154/* opens a user */ 154/* opens a user */
155{ 155{
156 int ret = 0; 156 int ret = 0;
157 157
158 memset(snac, '\0', sizeof(struct _snac)); 158 *user = (snac){0};
159 159
160 if (validate_uid(uid)) { 160 if (validate_uid(uid)) {
161 xs *cfg_file = NULL; 161 xs *cfg_file = NULL;
@@ -174,52 +174,52 @@ int user_open(snac *snac, const char *uid)
174 xs *v2 = xs_tolower_i(xs_dup(v)); 174 xs *v2 = xs_tolower_i(xs_dup(v));
175 175
176 if (strcmp(lcuid, v2) == 0) { 176 if (strcmp(lcuid, v2) == 0) {
177 snac->uid = xs_dup(v); 177 user->uid = xs_dup(v);
178 break; 178 break;
179 } 179 }
180 } 180 }
181 } 181 }
182 else 182 else
183 snac->uid = xs_str_new(uid); 183 user->uid = xs_str_new(uid);
184 184
185 if (snac->uid == NULL) 185 if (user->uid == NULL)
186 return ret; 186 return ret;
187 187
188 snac->basedir = xs_fmt("%s/user/%s", srv_basedir, snac->uid); 188 user->basedir = xs_fmt("%s/user/%s", srv_basedir, user->uid);
189 189
190 cfg_file = xs_fmt("%s/user.json", snac->basedir); 190 cfg_file = xs_fmt("%s/user.json", user->basedir);
191 191
192 if ((f = fopen(cfg_file, "r")) != NULL) { 192 if ((f = fopen(cfg_file, "r")) != NULL) {
193 /* read full config file */ 193 /* read full config file */
194 snac->config = xs_json_load(f); 194 user->config = xs_json_load(f);
195 fclose(f); 195 fclose(f);
196 196
197 if (snac->config != NULL) { 197 if (user->config != NULL) {
198 xs *key_file = xs_fmt("%s/key.json", snac->basedir); 198 xs *key_file = xs_fmt("%s/key.json", user->basedir);
199 199
200 if ((f = fopen(key_file, "r")) != NULL) { 200 if ((f = fopen(key_file, "r")) != NULL) {
201 snac->key = xs_json_load(f); 201 user->key = xs_json_load(f);
202 fclose(f); 202 fclose(f);
203 203
204 if (snac->key != NULL) { 204 if (user->key != NULL) {
205 snac->actor = xs_fmt("%s/%s", srv_baseurl, snac->uid); 205 user->actor = xs_fmt("%s/%s", srv_baseurl, user->uid);
206 snac->md5 = xs_md5_hex(snac->actor, strlen(snac->actor)); 206 user->md5 = xs_md5_hex(user->actor, strlen(user->actor));
207 207
208 /* everything is ok right now */ 208 /* everything is ok right now */
209 ret = 1; 209 ret = 1;
210 210
211 /* does it have a configuration override? */ 211 /* does it have a configuration override? */
212 xs *cfg_file_o = xs_fmt("%s/user_o.json", snac->basedir); 212 xs *cfg_file_o = xs_fmt("%s/user_o.json", user->basedir);
213 if ((f = fopen(cfg_file_o, "r")) != NULL) { 213 if ((f = fopen(cfg_file_o, "r")) != NULL) {
214 snac->config_o = xs_json_load(f); 214 user->config_o = xs_json_load(f);
215 fclose(f); 215 fclose(f);
216 216
217 if (snac->config_o == NULL) 217 if (user->config_o == NULL)
218 srv_log(xs_fmt("error parsing '%s'", cfg_file_o)); 218 srv_log(xs_fmt("error parsing '%s'", cfg_file_o));
219 } 219 }
220 220
221 if (snac->config_o == NULL) 221 if (user->config_o == NULL)
222 snac->config_o = xs_dict_new(); 222 user->config_o = xs_dict_new();
223 } 223 }
224 else 224 else
225 srv_log(xs_fmt("error parsing '%s'", key_file)); 225 srv_log(xs_fmt("error parsing '%s'", key_file));
@@ -237,7 +237,7 @@ int user_open(snac *snac, const char *uid)
237 srv_debug(1, xs_fmt("invalid user '%s'", uid)); 237 srv_debug(1, xs_fmt("invalid user '%s'", uid));
238 238
239 if (!ret) 239 if (!ret)
240 user_free(snac); 240 user_free(user);
241 241
242 return ret; 242 return ret;
243} 243}
diff --git a/httpd.c b/httpd.c
index 25740df..8c7e715 100644
--- a/httpd.c
+++ b/httpd.c
@@ -26,11 +26,10 @@
26#include <poll.h> 26#include <poll.h>
27#endif 27#endif
28 28
29int use_fcgi = 0; 29/** server stat **/
30 30
31int srv_running = 0; 31srv_stat s_stat = {0};
32 32srv_stat *p_stat = NULL;
33time_t srv_start_time = 0;
34 33
35/** job control **/ 34/** job control **/
36 35
@@ -229,13 +228,9 @@ int server_get_handler(xs_dict *req, const char *q_path,
229 *ctype = "text/plain"; 228 *ctype = "text/plain";
230 *body = xs_str_new("UP\n"); 229 *body = xs_str_new("UP\n");
231 230
232 xs *uptime = xs_str_time_diff(time(NULL) - srv_start_time); 231 xs *uptime = xs_str_time_diff(time(NULL) - p_stat->srv_start_time);
233 srv_log(xs_fmt("status: uptime: %s", uptime)); 232 srv_log(xs_fmt("status: uptime: %s", uptime));
234 233 srv_log(xs_fmt("status: job_fifo len: %d", p_stat->job_fifo_size));
235 pthread_mutex_lock(&job_mutex);
236 int l = xs_list_len(job_fifo);
237 pthread_mutex_unlock(&job_mutex);
238 srv_log(xs_fmt("status: job_fifo len: %d", l));
239 } 234 }
240 235
241 if (status != 0) 236 if (status != 0)
@@ -262,7 +257,7 @@ void httpd_connection(FILE *f)
262 char *p; 257 char *p;
263 int fcgi_id; 258 int fcgi_id;
264 259
265 if (use_fcgi) 260 if (p_stat->use_fcgi)
266 req = xs_fcgi_request(f, &payload, &p_size, &fcgi_id); 261 req = xs_fcgi_request(f, &payload, &p_size, &fcgi_id);
267 else 262 else
268 req = xs_httpd_request(f, &payload, &p_size); 263 req = xs_httpd_request(f, &payload, &p_size);
@@ -400,7 +395,7 @@ void httpd_connection(FILE *f)
400 headers = xs_dict_append(headers, "access-control-allow-origin", "*"); 395 headers = xs_dict_append(headers, "access-control-allow-origin", "*");
401 headers = xs_dict_append(headers, "access-control-allow-headers", "*"); 396 headers = xs_dict_append(headers, "access-control-allow-headers", "*");
402 397
403 if (use_fcgi) 398 if (p_stat->use_fcgi)
404 xs_fcgi_response(f, status, headers, body, b_size, fcgi_id); 399 xs_fcgi_response(f, status, headers, body, b_size, fcgi_id);
405 else 400 else
406 xs_httpd_response(f, status, headers, body, b_size); 401 xs_httpd_response(f, status, headers, body, b_size);
@@ -454,6 +449,8 @@ void job_post(const xs_val *job, int urgent)
454 job_fifo = xs_list_insert(job_fifo, 0, job); 449 job_fifo = xs_list_insert(job_fifo, 0, job);
455 else 450 else
456 job_fifo = xs_list_append(job_fifo, job); 451 job_fifo = xs_list_append(job_fifo, job);
452
453 p_stat->job_fifo_size++;
457 } 454 }
458 455
459 /* unlock the mutex */ 456 /* unlock the mutex */
@@ -475,9 +472,12 @@ void job_wait(xs_val **job)
475 pthread_mutex_lock(&job_mutex); 472 pthread_mutex_lock(&job_mutex);
476 473
477 /* dequeue */ 474 /* dequeue */
478 if (job_fifo != NULL) 475 if (job_fifo != NULL) {
479 job_fifo = xs_list_shift(job_fifo, job); 476 job_fifo = xs_list_shift(job_fifo, job);
480 477
478 p_stat->job_fifo_size--;
479 }
480
481 /* unlock the mutex */ 481 /* unlock the mutex */
482 pthread_mutex_unlock(&job_mutex); 482 pthread_mutex_unlock(&job_mutex);
483 } 483 }
@@ -541,7 +541,7 @@ static void *background_thread(void *arg)
541 541
542 srv_log(xs_fmt("background thread started")); 542 srv_log(xs_fmt("background thread started"));
543 543
544 while (srv_running) { 544 while (p_stat->srv_running) {
545 time_t t; 545 time_t t;
546 int cnt = 0; 546 int cnt = 0;
547 547
@@ -605,14 +605,18 @@ void httpd(void)
605 const char *port; 605 const char *port;
606 int rs; 606 int rs;
607 pthread_t threads[MAX_THREADS] = {0}; 607 pthread_t threads[MAX_THREADS] = {0};
608 int n_threads = 0;
609 int n; 608 int n;
610 char sem_name[24]; 609 xs *sem_name = NULL;
611 sem_t anon_job_sem; 610 sem_t anon_job_sem;
612 611
613 srv_start_time = time(NULL); 612 /* setup the server stat structure */
613 {
614 p_stat = &s_stat;
615 }
616
617 p_stat->srv_start_time = time(NULL);
614 618
615 use_fcgi = xs_type(xs_dict_get(srv_config, "fastcgi")) == XSTYPE_TRUE; 619 p_stat->use_fcgi = xs_type(xs_dict_get(srv_config, "fastcgi")) == XSTYPE_TRUE;
616 620
617 address = xs_dict_get(srv_config, "address"); 621 address = xs_dict_get(srv_config, "address");
618 port = xs_number_str(xs_dict_get(srv_config, "port")); 622 port = xs_number_str(xs_dict_get(srv_config, "port"));
@@ -622,13 +626,13 @@ void httpd(void)
622 return; 626 return;
623 } 627 }
624 628
625 srv_running = 1; 629 p_stat->srv_running = 1;
626 630
627 signal(SIGPIPE, SIG_IGN); 631 signal(SIGPIPE, SIG_IGN);
628 signal(SIGTERM, term_handler); 632 signal(SIGTERM, term_handler);
629 signal(SIGINT, term_handler); 633 signal(SIGINT, term_handler);
630 634
631 srv_log(xs_fmt("httpd%s start %s:%s %s", use_fcgi ? " (FastCGI)" : "", 635 srv_log(xs_fmt("httpd%s start %s:%s %s", p_stat->use_fcgi ? " (FastCGI)" : "",
632 address, port, USER_AGENT)); 636 address, port, USER_AGENT));
633 637
634 /* show the number of usable file descriptors */ 638 /* show the number of usable file descriptors */
@@ -639,7 +643,7 @@ void httpd(void)
639 643
640 /* initialize the job control engine */ 644 /* initialize the job control engine */
641 pthread_mutex_init(&job_mutex, NULL); 645 pthread_mutex_init(&job_mutex, NULL);
642 snprintf(sem_name, sizeof(sem_name), "/job_%d", getpid()); 646 sem_name = xs_fmt("/job_%d", getpid());
643 job_sem = sem_open(sem_name, O_CREAT, 0644, 0); 647 job_sem = sem_open(sem_name, O_CREAT, 0644, 0);
644 648
645 if (job_sem == NULL) { 649 if (job_sem == NULL) {
@@ -659,29 +663,29 @@ void httpd(void)
659 pthread_mutex_init(&sleep_mutex, NULL); 663 pthread_mutex_init(&sleep_mutex, NULL);
660 pthread_cond_init(&sleep_cond, NULL); 664 pthread_cond_init(&sleep_cond, NULL);
661 665
662 n_threads = xs_number_get(xs_dict_get(srv_config, "num_threads")); 666 p_stat->n_threads = xs_number_get(xs_dict_get(srv_config, "num_threads"));
663 667
664#ifdef _SC_NPROCESSORS_ONLN 668#ifdef _SC_NPROCESSORS_ONLN
665 if (n_threads == 0) { 669 if (p_stat->n_threads == 0) {
666 /* get number of CPUs on the machine */ 670 /* get number of CPUs on the machine */
667 n_threads = sysconf(_SC_NPROCESSORS_ONLN); 671 p_stat->n_threads = sysconf(_SC_NPROCESSORS_ONLN);
668 } 672 }
669#endif 673#endif
670 674
671 if (n_threads < 4) 675 if (p_stat->n_threads < 4)
672 n_threads = 4; 676 p_stat->n_threads = 4;
673 677
674 if (n_threads > MAX_THREADS) 678 if (p_stat->n_threads > MAX_THREADS)
675 n_threads = MAX_THREADS; 679 p_stat->n_threads = MAX_THREADS;
676 680
677 srv_debug(0, xs_fmt("using %d threads", n_threads)); 681 srv_debug(0, xs_fmt("using %d threads", p_stat->n_threads));
678 682
679 /* thread #0 is the background thread */ 683 /* thread #0 is the background thread */
680 pthread_create(&threads[0], NULL, background_thread, NULL); 684 pthread_create(&threads[0], NULL, background_thread, NULL);
681 685
682 /* the rest of threads are for job processing */ 686 /* the rest of threads are for job processing */
683 char *ptr = (char *) 0x1; 687 char *ptr = (char *) 0x1;
684 for (n = 1; n < n_threads; n++) 688 for (n = 1; n < p_stat->n_threads; n++)
685 pthread_create(&threads[n], NULL, job_thread, ptr++); 689 pthread_create(&threads[n], NULL, job_thread, ptr++);
686 690
687 if (setjmp(on_break) == 0) { 691 if (setjmp(on_break) == 0) {
@@ -697,14 +701,14 @@ void httpd(void)
697 } 701 }
698 } 702 }
699 703
700 srv_running = 0; 704 p_stat->srv_running = 0;
701 705
702 /* send as many empty jobs as working threads */ 706 /* send as many empty jobs as working threads */
703 for (n = 1; n < n_threads; n++) 707 for (n = 1; n < p_stat->n_threads; n++)
704 job_post(NULL, 0); 708 job_post(NULL, 0);
705 709
706 /* wait for all the threads to exit */ 710 /* wait for all the threads to exit */
707 for (n = 0; n < n_threads; n++) 711 for (n = 0; n < p_stat->n_threads; n++)
708 pthread_join(threads[n], NULL); 712 pthread_join(threads[n], NULL);
709 713
710 pthread_mutex_lock(&job_mutex); 714 pthread_mutex_lock(&job_mutex);
@@ -714,8 +718,9 @@ void httpd(void)
714 sem_close(job_sem); 718 sem_close(job_sem);
715 sem_unlink(sem_name); 719 sem_unlink(sem_name);
716 720
717 xs *uptime = xs_str_time_diff(time(NULL) - srv_start_time); 721 xs *uptime = xs_str_time_diff(time(NULL) - p_stat->srv_start_time);
718 722
719 srv_log(xs_fmt("httpd%s stop %s:%s (run time: %s)", use_fcgi ? " (FastCGI)" : "", 723 srv_log(xs_fmt("httpd%s stop %s:%s (run time: %s)",
724 p_stat->use_fcgi ? " (FastCGI)" : "",
720 address, port, uptime)); 725 address, port, uptime));
721} 726}
diff --git a/snac.h b/snac.h
index ba71ec6..4450010 100644
--- a/snac.h
+++ b/snac.h
@@ -31,7 +31,7 @@ void srv_log(xs_str *str);
31#define srv_debug(level, str) do { if (dbglevel >= (level)) \ 31#define srv_debug(level, str) do { if (dbglevel >= (level)) \
32 { srv_log((str)); } } while (0) 32 { srv_log((str)); } } while (0)
33 33
34typedef struct _snac { 34typedef struct {
35 xs_str *uid; /* uid */ 35 xs_str *uid; /* uid */
36 xs_str *basedir; /* user base directory */ 36 xs_str *basedir; /* user base directory */
37 xs_dict *config; /* user configuration */ 37 xs_dict *config; /* user configuration */
@@ -41,6 +41,14 @@ typedef struct _snac {
41 xs_str *md5; /* actor url md5 */ 41 xs_str *md5; /* actor url md5 */
42} snac; 42} snac;
43 43
44typedef struct {
45 int srv_running; /* server running on/off */
46 int use_fcgi; /* FastCGI use on/off */
47 time_t srv_start_time; /* start time */
48 int job_fifo_size; /* job fifo size */
49 int n_threads; /* number of configured threads */
50} srv_stat;
51
44void snac_log(snac *user, xs_str *str); 52void snac_log(snac *user, xs_str *str);
45#define snac_debug(user, level, str) do { if (dbglevel >= (level)) \ 53#define snac_debug(user, level, str) do { if (dbglevel >= (level)) \
46 { snac_log((user), (str)); } } while (0) 54 { snac_log((user), (str)); } } while (0)