mirror of
https://codeberg.org/grunfink/snac2.git
synced 2024-11-25 14:35:04 +00:00
Moved most server state to a structure.
This commit is contained in:
parent
607335aa74
commit
e003f87c2d
3 changed files with 69 additions and 56 deletions
40
data.c
40
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 */
|
/* opens a user */
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
memset(snac, '\0', sizeof(struct _snac));
|
*user = (snac){0};
|
||||||
|
|
||||||
if (validate_uid(uid)) {
|
if (validate_uid(uid)) {
|
||||||
xs *cfg_file = NULL;
|
xs *cfg_file = NULL;
|
||||||
|
@ -174,52 +174,52 @@ int user_open(snac *snac, const char *uid)
|
||||||
xs *v2 = xs_tolower_i(xs_dup(v));
|
xs *v2 = xs_tolower_i(xs_dup(v));
|
||||||
|
|
||||||
if (strcmp(lcuid, v2) == 0) {
|
if (strcmp(lcuid, v2) == 0) {
|
||||||
snac->uid = xs_dup(v);
|
user->uid = xs_dup(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
snac->uid = xs_str_new(uid);
|
user->uid = xs_str_new(uid);
|
||||||
|
|
||||||
if (snac->uid == NULL)
|
if (user->uid == NULL)
|
||||||
return ret;
|
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) {
|
if ((f = fopen(cfg_file, "r")) != NULL) {
|
||||||
/* read full config file */
|
/* read full config file */
|
||||||
snac->config = xs_json_load(f);
|
user->config = xs_json_load(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (snac->config != NULL) {
|
if (user->config != NULL) {
|
||||||
xs *key_file = xs_fmt("%s/key.json", snac->basedir);
|
xs *key_file = xs_fmt("%s/key.json", user->basedir);
|
||||||
|
|
||||||
if ((f = fopen(key_file, "r")) != NULL) {
|
if ((f = fopen(key_file, "r")) != NULL) {
|
||||||
snac->key = xs_json_load(f);
|
user->key = xs_json_load(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (snac->key != NULL) {
|
if (user->key != NULL) {
|
||||||
snac->actor = xs_fmt("%s/%s", srv_baseurl, snac->uid);
|
user->actor = xs_fmt("%s/%s", srv_baseurl, user->uid);
|
||||||
snac->md5 = xs_md5_hex(snac->actor, strlen(snac->actor));
|
user->md5 = xs_md5_hex(user->actor, strlen(user->actor));
|
||||||
|
|
||||||
/* everything is ok right now */
|
/* everything is ok right now */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
/* does it have a configuration override? */
|
/* 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) {
|
if ((f = fopen(cfg_file_o, "r")) != NULL) {
|
||||||
snac->config_o = xs_json_load(f);
|
user->config_o = xs_json_load(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (snac->config_o == NULL)
|
if (user->config_o == NULL)
|
||||||
srv_log(xs_fmt("error parsing '%s'", cfg_file_o));
|
srv_log(xs_fmt("error parsing '%s'", cfg_file_o));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snac->config_o == NULL)
|
if (user->config_o == NULL)
|
||||||
snac->config_o = xs_dict_new();
|
user->config_o = xs_dict_new();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
srv_log(xs_fmt("error parsing '%s'", key_file));
|
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));
|
srv_debug(1, xs_fmt("invalid user '%s'", uid));
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
user_free(snac);
|
user_free(user);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
75
httpd.c
75
httpd.c
|
@ -26,11 +26,10 @@
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int use_fcgi = 0;
|
/** server stat **/
|
||||||
|
|
||||||
int srv_running = 0;
|
srv_stat s_stat = {0};
|
||||||
|
srv_stat *p_stat = NULL;
|
||||||
time_t srv_start_time = 0;
|
|
||||||
|
|
||||||
/** job control **/
|
/** job control **/
|
||||||
|
|
||||||
|
@ -229,13 +228,9 @@ int server_get_handler(xs_dict *req, const char *q_path,
|
||||||
*ctype = "text/plain";
|
*ctype = "text/plain";
|
||||||
*body = xs_str_new("UP\n");
|
*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));
|
srv_log(xs_fmt("status: uptime: %s", uptime));
|
||||||
|
srv_log(xs_fmt("status: job_fifo len: %d", p_stat->job_fifo_size));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
|
@ -262,7 +257,7 @@ void httpd_connection(FILE *f)
|
||||||
char *p;
|
char *p;
|
||||||
int fcgi_id;
|
int fcgi_id;
|
||||||
|
|
||||||
if (use_fcgi)
|
if (p_stat->use_fcgi)
|
||||||
req = xs_fcgi_request(f, &payload, &p_size, &fcgi_id);
|
req = xs_fcgi_request(f, &payload, &p_size, &fcgi_id);
|
||||||
else
|
else
|
||||||
req = xs_httpd_request(f, &payload, &p_size);
|
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-origin", "*");
|
||||||
headers = xs_dict_append(headers, "access-control-allow-headers", "*");
|
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);
|
xs_fcgi_response(f, status, headers, body, b_size, fcgi_id);
|
||||||
else
|
else
|
||||||
xs_httpd_response(f, status, headers, body, b_size);
|
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);
|
job_fifo = xs_list_insert(job_fifo, 0, job);
|
||||||
else
|
else
|
||||||
job_fifo = xs_list_append(job_fifo, job);
|
job_fifo = xs_list_append(job_fifo, job);
|
||||||
|
|
||||||
|
p_stat->job_fifo_size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unlock the mutex */
|
/* unlock the mutex */
|
||||||
|
@ -475,9 +472,12 @@ void job_wait(xs_val **job)
|
||||||
pthread_mutex_lock(&job_mutex);
|
pthread_mutex_lock(&job_mutex);
|
||||||
|
|
||||||
/* dequeue */
|
/* dequeue */
|
||||||
if (job_fifo != NULL)
|
if (job_fifo != NULL) {
|
||||||
job_fifo = xs_list_shift(job_fifo, job);
|
job_fifo = xs_list_shift(job_fifo, job);
|
||||||
|
|
||||||
|
p_stat->job_fifo_size--;
|
||||||
|
}
|
||||||
|
|
||||||
/* unlock the mutex */
|
/* unlock the mutex */
|
||||||
pthread_mutex_unlock(&job_mutex);
|
pthread_mutex_unlock(&job_mutex);
|
||||||
}
|
}
|
||||||
|
@ -541,7 +541,7 @@ static void *background_thread(void *arg)
|
||||||
|
|
||||||
srv_log(xs_fmt("background thread started"));
|
srv_log(xs_fmt("background thread started"));
|
||||||
|
|
||||||
while (srv_running) {
|
while (p_stat->srv_running) {
|
||||||
time_t t;
|
time_t t;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
|
@ -605,14 +605,18 @@ void httpd(void)
|
||||||
const char *port;
|
const char *port;
|
||||||
int rs;
|
int rs;
|
||||||
pthread_t threads[MAX_THREADS] = {0};
|
pthread_t threads[MAX_THREADS] = {0};
|
||||||
int n_threads = 0;
|
|
||||||
int n;
|
int n;
|
||||||
char sem_name[24];
|
xs *sem_name = NULL;
|
||||||
sem_t anon_job_sem;
|
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");
|
address = xs_dict_get(srv_config, "address");
|
||||||
port = xs_number_str(xs_dict_get(srv_config, "port"));
|
port = xs_number_str(xs_dict_get(srv_config, "port"));
|
||||||
|
@ -622,13 +626,13 @@ void httpd(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
srv_running = 1;
|
p_stat->srv_running = 1;
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
signal(SIGTERM, term_handler);
|
signal(SIGTERM, term_handler);
|
||||||
signal(SIGINT, 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));
|
address, port, USER_AGENT));
|
||||||
|
|
||||||
/* show the number of usable file descriptors */
|
/* show the number of usable file descriptors */
|
||||||
|
@ -639,7 +643,7 @@ void httpd(void)
|
||||||
|
|
||||||
/* initialize the job control engine */
|
/* initialize the job control engine */
|
||||||
pthread_mutex_init(&job_mutex, NULL);
|
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);
|
job_sem = sem_open(sem_name, O_CREAT, 0644, 0);
|
||||||
|
|
||||||
if (job_sem == NULL) {
|
if (job_sem == NULL) {
|
||||||
|
@ -659,29 +663,29 @@ void httpd(void)
|
||||||
pthread_mutex_init(&sleep_mutex, NULL);
|
pthread_mutex_init(&sleep_mutex, NULL);
|
||||||
pthread_cond_init(&sleep_cond, 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
|
#ifdef _SC_NPROCESSORS_ONLN
|
||||||
if (n_threads == 0) {
|
if (p_stat->n_threads == 0) {
|
||||||
/* get number of CPUs on the machine */
|
/* get number of CPUs on the machine */
|
||||||
n_threads = sysconf(_SC_NPROCESSORS_ONLN);
|
p_stat->n_threads = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (n_threads < 4)
|
if (p_stat->n_threads < 4)
|
||||||
n_threads = 4;
|
p_stat->n_threads = 4;
|
||||||
|
|
||||||
if (n_threads > MAX_THREADS)
|
if (p_stat->n_threads > MAX_THREADS)
|
||||||
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 */
|
/* thread #0 is the background thread */
|
||||||
pthread_create(&threads[0], NULL, background_thread, NULL);
|
pthread_create(&threads[0], NULL, background_thread, NULL);
|
||||||
|
|
||||||
/* the rest of threads are for job processing */
|
/* the rest of threads are for job processing */
|
||||||
char *ptr = (char *) 0x1;
|
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++);
|
pthread_create(&threads[n], NULL, job_thread, ptr++);
|
||||||
|
|
||||||
if (setjmp(on_break) == 0) {
|
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 */
|
/* 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);
|
job_post(NULL, 0);
|
||||||
|
|
||||||
/* wait for all the threads to exit */
|
/* 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_join(threads[n], NULL);
|
||||||
|
|
||||||
pthread_mutex_lock(&job_mutex);
|
pthread_mutex_lock(&job_mutex);
|
||||||
|
@ -714,8 +718,9 @@ void httpd(void)
|
||||||
sem_close(job_sem);
|
sem_close(job_sem);
|
||||||
sem_unlink(sem_name);
|
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));
|
address, port, uptime));
|
||||||
}
|
}
|
||||||
|
|
10
snac.h
10
snac.h
|
@ -31,7 +31,7 @@ void srv_log(xs_str *str);
|
||||||
#define srv_debug(level, str) do { if (dbglevel >= (level)) \
|
#define srv_debug(level, str) do { if (dbglevel >= (level)) \
|
||||||
{ srv_log((str)); } } while (0)
|
{ srv_log((str)); } } while (0)
|
||||||
|
|
||||||
typedef struct _snac {
|
typedef struct {
|
||||||
xs_str *uid; /* uid */
|
xs_str *uid; /* uid */
|
||||||
xs_str *basedir; /* user base directory */
|
xs_str *basedir; /* user base directory */
|
||||||
xs_dict *config; /* user configuration */
|
xs_dict *config; /* user configuration */
|
||||||
|
@ -41,6 +41,14 @@ typedef struct _snac {
|
||||||
xs_str *md5; /* actor url md5 */
|
xs_str *md5; /* actor url md5 */
|
||||||
} snac;
|
} 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);
|
void snac_log(snac *user, xs_str *str);
|
||||||
#define snac_debug(user, level, str) do { if (dbglevel >= (level)) \
|
#define snac_debug(user, level, str) do { if (dbglevel >= (level)) \
|
||||||
{ snac_log((user), (str)); } } while (0)
|
{ snac_log((user), (str)); } } while (0)
|
||||||
|
|
Loading…
Reference in a new issue