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) } -int user_open(snac *snac, const char *uid) +int user_open(snac *user, const char *uid) /* opens a user */ { int ret = 0; - memset(snac, '\0', sizeof(struct _snac)); + *user = (snac){0}; if (validate_uid(uid)) { xs *cfg_file = NULL; @@ -174,52 +174,52 @@ int user_open(snac *snac, const char *uid) xs *v2 = xs_tolower_i(xs_dup(v)); if (strcmp(lcuid, v2) == 0) { - snac->uid = xs_dup(v); + user->uid = xs_dup(v); break; } } } else - snac->uid = xs_str_new(uid); + user->uid = xs_str_new(uid); - if (snac->uid == NULL) + if (user->uid == NULL) return ret; - snac->basedir = xs_fmt("%s/user/%s", srv_basedir, snac->uid); + user->basedir = xs_fmt("%s/user/%s", srv_basedir, user->uid); - cfg_file = xs_fmt("%s/user.json", snac->basedir); + cfg_file = xs_fmt("%s/user.json", user->basedir); if ((f = fopen(cfg_file, "r")) != NULL) { /* read full config file */ - snac->config = xs_json_load(f); + user->config = xs_json_load(f); fclose(f); - if (snac->config != NULL) { - xs *key_file = xs_fmt("%s/key.json", snac->basedir); + if (user->config != NULL) { + xs *key_file = xs_fmt("%s/key.json", user->basedir); if ((f = fopen(key_file, "r")) != NULL) { - snac->key = xs_json_load(f); + user->key = xs_json_load(f); fclose(f); - if (snac->key != NULL) { - snac->actor = xs_fmt("%s/%s", srv_baseurl, snac->uid); - snac->md5 = xs_md5_hex(snac->actor, strlen(snac->actor)); + if (user->key != NULL) { + user->actor = xs_fmt("%s/%s", srv_baseurl, user->uid); + user->md5 = xs_md5_hex(user->actor, strlen(user->actor)); /* everything is ok right now */ ret = 1; /* does it have a configuration override? */ - xs *cfg_file_o = xs_fmt("%s/user_o.json", snac->basedir); + xs *cfg_file_o = xs_fmt("%s/user_o.json", user->basedir); if ((f = fopen(cfg_file_o, "r")) != NULL) { - snac->config_o = xs_json_load(f); + user->config_o = xs_json_load(f); fclose(f); - if (snac->config_o == NULL) + if (user->config_o == NULL) srv_log(xs_fmt("error parsing '%s'", cfg_file_o)); } - if (snac->config_o == NULL) - snac->config_o = xs_dict_new(); + if (user->config_o == NULL) + user->config_o = xs_dict_new(); } else srv_log(xs_fmt("error parsing '%s'", key_file)); @@ -237,7 +237,7 @@ int user_open(snac *snac, const char *uid) srv_debug(1, xs_fmt("invalid user '%s'", uid)); if (!ret) - user_free(snac); + user_free(user); return ret; } diff --git a/httpd.c b/httpd.c index 25740df..8c7e715 100644 --- a/httpd.c +++ b/httpd.c @@ -26,11 +26,10 @@ #include #endif -int use_fcgi = 0; +/** server stat **/ -int srv_running = 0; - -time_t srv_start_time = 0; +srv_stat s_stat = {0}; +srv_stat *p_stat = NULL; /** job control **/ @@ -229,13 +228,9 @@ int server_get_handler(xs_dict *req, const char *q_path, *ctype = "text/plain"; *body = xs_str_new("UP\n"); - xs *uptime = xs_str_time_diff(time(NULL) - srv_start_time); + xs *uptime = xs_str_time_diff(time(NULL) - p_stat->srv_start_time); srv_log(xs_fmt("status: uptime: %s", uptime)); - - pthread_mutex_lock(&job_mutex); - int l = xs_list_len(job_fifo); - pthread_mutex_unlock(&job_mutex); - srv_log(xs_fmt("status: job_fifo len: %d", l)); + srv_log(xs_fmt("status: job_fifo len: %d", p_stat->job_fifo_size)); } if (status != 0) @@ -262,7 +257,7 @@ void httpd_connection(FILE *f) char *p; int fcgi_id; - if (use_fcgi) + if (p_stat->use_fcgi) req = xs_fcgi_request(f, &payload, &p_size, &fcgi_id); else req = xs_httpd_request(f, &payload, &p_size); @@ -400,7 +395,7 @@ void httpd_connection(FILE *f) headers = xs_dict_append(headers, "access-control-allow-origin", "*"); headers = xs_dict_append(headers, "access-control-allow-headers", "*"); - if (use_fcgi) + if (p_stat->use_fcgi) xs_fcgi_response(f, status, headers, body, b_size, fcgi_id); else xs_httpd_response(f, status, headers, body, b_size); @@ -454,6 +449,8 @@ void job_post(const xs_val *job, int urgent) job_fifo = xs_list_insert(job_fifo, 0, job); else job_fifo = xs_list_append(job_fifo, job); + + p_stat->job_fifo_size++; } /* unlock the mutex */ @@ -475,9 +472,12 @@ void job_wait(xs_val **job) pthread_mutex_lock(&job_mutex); /* dequeue */ - if (job_fifo != NULL) + if (job_fifo != NULL) { job_fifo = xs_list_shift(job_fifo, job); + p_stat->job_fifo_size--; + } + /* unlock the mutex */ pthread_mutex_unlock(&job_mutex); } @@ -541,7 +541,7 @@ static void *background_thread(void *arg) srv_log(xs_fmt("background thread started")); - while (srv_running) { + while (p_stat->srv_running) { time_t t; int cnt = 0; @@ -605,14 +605,18 @@ void httpd(void) const char *port; int rs; pthread_t threads[MAX_THREADS] = {0}; - int n_threads = 0; int n; - char sem_name[24]; + xs *sem_name = NULL; sem_t anon_job_sem; - srv_start_time = time(NULL); + /* setup the server stat structure */ + { + p_stat = &s_stat; + } - use_fcgi = xs_type(xs_dict_get(srv_config, "fastcgi")) == XSTYPE_TRUE; + p_stat->srv_start_time = time(NULL); + + p_stat->use_fcgi = xs_type(xs_dict_get(srv_config, "fastcgi")) == XSTYPE_TRUE; address = xs_dict_get(srv_config, "address"); port = xs_number_str(xs_dict_get(srv_config, "port")); @@ -622,13 +626,13 @@ void httpd(void) return; } - srv_running = 1; + p_stat->srv_running = 1; signal(SIGPIPE, SIG_IGN); signal(SIGTERM, term_handler); signal(SIGINT, term_handler); - srv_log(xs_fmt("httpd%s start %s:%s %s", use_fcgi ? " (FastCGI)" : "", + srv_log(xs_fmt("httpd%s start %s:%s %s", p_stat->use_fcgi ? " (FastCGI)" : "", address, port, USER_AGENT)); /* show the number of usable file descriptors */ @@ -639,7 +643,7 @@ void httpd(void) /* initialize the job control engine */ pthread_mutex_init(&job_mutex, NULL); - snprintf(sem_name, sizeof(sem_name), "/job_%d", getpid()); + sem_name = xs_fmt("/job_%d", getpid()); job_sem = sem_open(sem_name, O_CREAT, 0644, 0); if (job_sem == NULL) { @@ -659,29 +663,29 @@ void httpd(void) pthread_mutex_init(&sleep_mutex, NULL); pthread_cond_init(&sleep_cond, NULL); - n_threads = xs_number_get(xs_dict_get(srv_config, "num_threads")); + p_stat->n_threads = xs_number_get(xs_dict_get(srv_config, "num_threads")); #ifdef _SC_NPROCESSORS_ONLN - if (n_threads == 0) { + if (p_stat->n_threads == 0) { /* get number of CPUs on the machine */ - n_threads = sysconf(_SC_NPROCESSORS_ONLN); + p_stat->n_threads = sysconf(_SC_NPROCESSORS_ONLN); } #endif - if (n_threads < 4) - n_threads = 4; + if (p_stat->n_threads < 4) + p_stat->n_threads = 4; - if (n_threads > MAX_THREADS) - n_threads = MAX_THREADS; + if (p_stat->n_threads > MAX_THREADS) + p_stat->n_threads = MAX_THREADS; - srv_debug(0, xs_fmt("using %d threads", n_threads)); + srv_debug(0, xs_fmt("using %d threads", p_stat->n_threads)); /* thread #0 is the background thread */ pthread_create(&threads[0], NULL, background_thread, NULL); /* the rest of threads are for job processing */ char *ptr = (char *) 0x1; - for (n = 1; n < n_threads; n++) + for (n = 1; n < p_stat->n_threads; n++) pthread_create(&threads[n], NULL, job_thread, ptr++); if (setjmp(on_break) == 0) { @@ -697,14 +701,14 @@ void httpd(void) } } - srv_running = 0; + p_stat->srv_running = 0; /* send as many empty jobs as working threads */ - for (n = 1; n < n_threads; n++) + for (n = 1; n < p_stat->n_threads; n++) job_post(NULL, 0); /* wait for all the threads to exit */ - for (n = 0; n < n_threads; n++) + for (n = 0; n < p_stat->n_threads; n++) pthread_join(threads[n], NULL); pthread_mutex_lock(&job_mutex); @@ -714,8 +718,9 @@ void httpd(void) sem_close(job_sem); sem_unlink(sem_name); - xs *uptime = xs_str_time_diff(time(NULL) - srv_start_time); + xs *uptime = xs_str_time_diff(time(NULL) - p_stat->srv_start_time); - srv_log(xs_fmt("httpd%s stop %s:%s (run time: %s)", use_fcgi ? " (FastCGI)" : "", + srv_log(xs_fmt("httpd%s stop %s:%s (run time: %s)", + p_stat->use_fcgi ? " (FastCGI)" : "", address, port, uptime)); } 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); #define srv_debug(level, str) do { if (dbglevel >= (level)) \ { srv_log((str)); } } while (0) -typedef struct _snac { +typedef struct { xs_str *uid; /* uid */ xs_str *basedir; /* user base directory */ xs_dict *config; /* user configuration */ @@ -41,6 +41,14 @@ typedef struct _snac { xs_str *md5; /* actor url md5 */ } snac; +typedef struct { + int srv_running; /* server running on/off */ + int use_fcgi; /* FastCGI use on/off */ + time_t srv_start_time; /* start time */ + int job_fifo_size; /* job fifo size */ + int n_threads; /* number of configured threads */ +} srv_stat; + void snac_log(snac *user, xs_str *str); #define snac_debug(user, level, str) do { if (dbglevel >= (level)) \ { snac_log((user), (str)); } } while (0)