void lwan_init_with_config(struct lwan *l, const struct lwan_config *config) { /* Load defaults */ memset(l, 0, sizeof(*l)); memcpy(&l->config, config, sizeof(*config)); l->config.listener = dup_or_null(l->config.listener); l->config.config_file_path = dup_or_null(l->config.config_file_path); /* Initialize status first, as it is used by other things during * their initialization. */ lwan_status_init(l); /* These will only print debugging messages. Debug messages are always * printed if we're on a debug build, so the quiet setting will be * respected. */ lwan_job_thread_init(); lwan_tables_init(); try_setup_from_config(l, config); lwan_response_init(l); /* Continue initialization as normal. */ lwan_status_debug("Initializing lwan web server"); l->n_cpus = get_number_of_cpus(); if (!l->config.n_threads) { l->thread.count = l->n_cpus; if (l->thread.count == 1) l->thread.count = 2; } else if (l->config.n_threads > 3 * l->n_cpus) { l->thread.count = (short unsigned int)(l->n_cpus * 3); lwan_status_warning("%d threads requested, but only %d online CPUs; " "capping to %d threads", l->config.n_threads, l->n_cpus, 3 * l->n_cpus); } else if (l->config.n_threads > 63) { l->thread.count = 64; lwan_status_warning("%d threads requested, but max 64 supported", l->config.n_threads); } else { l->thread.count = l->config.n_threads; } rlim_t max_open_files = setup_open_file_count_limits(); allocate_connections(l, (size_t)max_open_files); l->thread.max_fd = (unsigned)max_open_files / (unsigned)l->thread.count; lwan_status_info("Using %d threads, maximum %d sockets per thread", l->thread.count, l->thread.max_fd); signal(SIGPIPE, SIG_IGN); lwan_readahead_init(); lwan_thread_init(l); lwan_socket_init(l); lwan_http_authorize_init(); lwan_fd_watch_init(l); }
unsigned int parse_time_period(const char *str, unsigned int default_value) { unsigned int total = 0; unsigned int period; char multiplier; if (!str) return default_value; while (*str && sscanf(str, "%u%c", &period, &multiplier) == 2) { switch (multiplier) { case 's': total += period; break; case 'm': total += period * ONE_MINUTE; break; case 'h': total += period * ONE_HOUR; break; case 'd': total += period * ONE_DAY; break; case 'w': total += period * ONE_WEEK; break; case 'M': total += period * ONE_MONTH; break; case 'y': total += period * ONE_YEAR; break; default: lwan_status_warning("Ignoring unknown multiplier: %c", multiplier); } str = (const char *)rawmemchr(str, multiplier) + 1; } return total ? total : default_value; }
static unsigned short int get_number_of_cpus(void) { long n_online_cpus = sysconf(_SC_NPROCESSORS_ONLN); if (UNLIKELY(n_online_cpus < 0)) { lwan_status_warning( "Could not get number of online CPUs, assuming 1 CPU"); return 1; } return (unsigned short int)n_online_cpus; }
void lwan_init(lwan_t *l) { int max_threads = sysconf(_SC_NPROCESSORS_ONLN); struct rlimit r; /* Load defaults */ memcpy(&l->config, &default_config, sizeof(default_config)); /* Initialize status first, as it is used by other things during * their initialization. */ lwan_status_init(l); /* These will only print debugging messages. Debug messages are always * printed if we're on a debug build, so the quiet setting will be * respected. */ lwan_job_thread_init(); lwan_response_init(); lwan_tables_init(); /* Load the configuration file. */ if (!setup_from_config(l)) lwan_status_warning("Could not read config file, using defaults"); /* Continue initialization as normal. */ lwan_status_debug("Initializing lwan web server"); l->thread.count = max_threads > 0 ? max_threads : 2; if (getrlimit(RLIMIT_NOFILE, &r) < 0) lwan_status_critical_perror("getrlimit"); if (r.rlim_max == RLIM_INFINITY) r.rlim_cur *= 8; else if (r.rlim_cur < r.rlim_max) r.rlim_cur = r.rlim_max; if (setrlimit(RLIMIT_NOFILE, &r) < 0) lwan_status_critical_perror("setrlimit"); l->conns = calloc(r.rlim_cur, sizeof(lwan_connection_t)); l->thread.max_fd = r.rlim_cur / l->thread.count; lwan_status_info("Using %d threads, maximum %d sockets per thread", l->thread.count, l->thread.max_fd); for (--r.rlim_cur; r.rlim_cur; --r.rlim_cur) l->conns[r.rlim_cur].response_buffer = strbuf_new(); srand(time(NULL)); signal(SIGPIPE, SIG_IGN); close(STDIN_FILENO); lwan_thread_init(l); lwan_socket_init(l); lwan_http_authorize_init(); }
void lwan_init_with_config(lwan_t *l, const lwan_config_t *config) { /* Load defaults */ memset(l, 0, sizeof(*l)); memcpy(&l->config, config, sizeof(*config)); /* Initialize status first, as it is used by other things during * their initialization. */ lwan_status_init(l); /* These will only print debugging messages. Debug messages are always * printed if we're on a debug build, so the quiet setting will be * respected. */ lwan_job_thread_init(); lwan_tables_init(); lwan_module_init(l); /* Load the configuration file. */ if (config == &default_config) { if (!setup_from_config(l)) lwan_status_warning("Could not read config file, using defaults"); /* `quiet` key might have changed value. */ lwan_status_init(l); } lwan_response_init(l); /* Continue initialization as normal. */ lwan_status_debug("Initializing lwan web server"); if (!l->config.n_threads) { l->thread.count = get_number_of_cpus(); if (l->thread.count == 1) l->thread.count = 2; } else { l->thread.count = l->config.n_threads; } rlim_t max_open_files = setup_open_file_count_limits(); allocate_connections(l, (size_t)max_open_files); l->thread.max_fd = (unsigned)max_open_files / (unsigned)l->thread.count; lwan_status_info("Using %d threads, maximum %d sockets per thread", l->thread.count, l->thread.max_fd); signal(SIGPIPE, SIG_IGN); lwan_thread_init(l); lwan_socket_init(l); lwan_http_authorize_init(); }