void uwsgi_setup_locking() { // use the fastest available locking if (uwsgi.lock_engine) { if (!strcmp(uwsgi.lock_engine, "ipcsem")) { uwsgi_log_initial("lock engine: ipcsem\n"); atexit(uwsgi_ipcsem_clear); uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init; uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check; uwsgi.lock_ops.lock = uwsgi_lock_ipcsem; uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem; uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init; uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check; uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem; uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem; uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem; uwsgi.lock_size = 8; uwsgi.rwlock_size = 8; return; } } uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME); #ifdef UWSGI_IPCSEM_ATEXIT atexit(uwsgi_ipcsem_clear); #endif uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init; uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check; uwsgi.lock_ops.lock = uwsgi_lock_fast; uwsgi.lock_ops.unlock = uwsgi_unlock_fast; uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init; uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check; uwsgi.lock_ops.rlock = uwsgi_rlock_fast; uwsgi.lock_ops.wlock = uwsgi_wlock_fast; uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast; uwsgi.lock_size = UWSGI_LOCK_SIZE; uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE; }
int uwsgi_python_init() { #ifndef UWSGI_PYPY char *pyversion = strchr(Py_GetVersion(), '\n'); if (!pyversion) { uwsgi_log_initial("Python version: %s\n", Py_GetVersion()); } else { uwsgi_log_initial("Python version: %.*s %s\n", pyversion-Py_GetVersion(), Py_GetVersion(), Py_GetCompiler()+1); } #else uwsgi_log_initial("PyPy version: %s\n", PYPY_VERSION); #endif if (up.home != NULL) { #ifdef PYTHREE wchar_t *wpyhome; wpyhome = malloc((sizeof(wchar_t) * strlen(up.home)) + sizeof(wchar_t) ); if (!wpyhome) { uwsgi_error("malloc()"); exit(1); } mbstowcs(wpyhome, up.home, strlen(up.home)); Py_SetPythonHome(wpyhome); // do not free this memory !!! //free(wpyhome); #else Py_SetPythonHome(up.home); #endif uwsgi_log("Set PythonHome to %s\n", up.home); } #ifdef PYTHREE wchar_t pname[6]; mbstowcs(pname, "uWSGI", 6); Py_SetProgramName(pname); #else Py_SetProgramName("uWSGI"); #endif #ifndef UWSGI_PYPY Py_OptimizeFlag = up.optimize; #endif Py_Initialize(); if (!uwsgi.has_threads) { uwsgi_log("*** Python threads support is disabled. You can enable it with --enable-threads ***\n"); } up.wsgi_spitout = PyCFunction_New(uwsgi_spit_method, NULL); up.wsgi_writeout = PyCFunction_New(uwsgi_write_method, NULL); up.main_thread = PyThreadState_Get(); // by default set a fake GIL (little impact on performance) up.gil_get = gil_fake_get; up.gil_release = gil_fake_release; up.swap_ts = simple_swap_ts; up.reset_ts = simple_reset_ts; uwsgi_log_initial("Python main interpreter initialized at %p\n", up.main_thread); return 1; }
void uwsgi_yaml_config(char *file, char *magic_table[]) { int len = 0; char *yaml; int in_uwsgi_section = 0; char *key = NULL; char *val = NULL; char *section_asked = "uwsgi"; char *colon; if (uwsgi_check_scheme(file)) { colon = uwsgi_get_last_char(file, '/'); colon = uwsgi_get_last_char(colon, ':'); } else { colon = uwsgi_get_last_char(file, ':'); } if (colon) { colon[0] = 0; if (colon[1] != 0) { section_asked = colon + 1; } } uwsgi_log_initial("[uWSGI] getting YAML configuration from %s\n", file); yaml = uwsgi_open_and_read(file, &len, 1, magic_table); #ifdef UWSGI_LIBYAML yaml_parser_t parser; yaml_token_t token; int status = 0; int parsing = 1; if (!yaml_parser_initialize(&parser)) { uwsgi_log("unable to initialize YAML parser (libyaml)\n"); exit(1); } yaml_parser_set_input_string(&parser, (unsigned char *) yaml, (size_t) len - 1); while (parsing) { if (!yaml_parser_scan(&parser, &token)) { uwsgi_log("error parsing YAML file: %s (%c)\n", parser.problem, yaml[parser.problem_offset]); exit(1); } switch (token.type) { case YAML_STREAM_END_TOKEN: parsing = 0; break; case YAML_KEY_TOKEN: status = 1; break; case YAML_VALUE_TOKEN: status = 2; break; case YAML_FLOW_SEQUENCE_START_TOKEN: case YAML_BLOCK_SEQUENCE_START_TOKEN: status = 3; break; case YAML_BLOCK_MAPPING_START_TOKEN: if (!in_uwsgi_section) { if (key) { if (!strcmp(section_asked, key)) { in_uwsgi_section = 1; } } } break; case YAML_BLOCK_END_TOKEN: if (in_uwsgi_section) { parsing = 0; break; } break; case YAML_SCALAR_TOKEN: case YAML_FLOW_ENTRY_TOKEN: case YAML_BLOCK_ENTRY_TOKEN: if (status == 1) { key = (char *) token.data.scalar.value; } else if (status == 2) { val = (char *) token.data.scalar.value; if (key && val && in_uwsgi_section) { add_exported_option(key, val, 0); } status = 0; } else if (status == 3) { val = (char *) token.data.scalar.value; if (key && val && in_uwsgi_section) { add_exported_option(key, val, 0); } } else { uwsgi_log("unsupported YAML token in %s block\n", section_asked); parsing = 0; break; } break; default: status = 0; } } #else int depth; int current_depth = 0; int lines = 1; char *yaml_line; char *section = ""; while (len) { yaml_line = yaml_get_line(yaml, len); if (yaml_line == NULL) { break; } lines++; // skip empty line if (yaml[0] == 0) goto next; depth = yaml_get_depth(yaml); if (depth <= current_depth) { current_depth = depth; // end the parsing cycle if (in_uwsgi_section) return; } else if (depth > current_depth && !in_uwsgi_section) { goto next; } key = yaml_lstrip(yaml); // skip empty line if (key[0] == 0) goto next; // skip list and {} defined dict if (key[0] == '-' || key[0] == '[' || key[0] == '{') { if (in_uwsgi_section) return; goto next; } if (!in_uwsgi_section) { section = strchr(key, ':'); if (!section) goto next; section[0] = 0; if (!strcmp(key, section_asked)) { in_uwsgi_section = 1; } } else { // get dict value val = strstr(key, ": "); if (!val) { val = strstr(key, ":\t"); } if (!val) return; // get the right key val[0] = 0; // yeah overengeneering.... yaml_rstrip(key); val = yaml_lstrip(val + 2); yaml_rstrip(val); //uwsgi_log("YAML: %s = %s\n", key, val); add_exported_option((char *) key, val, 0); } next: len -= (yaml_line - yaml); yaml += (yaml_line - yaml); } #endif }
void uwsgi_setup_locking() { int i; if (uwsgi.locking_setup) return; // use the fastest available locking if (uwsgi.lock_engine) { if (!strcmp(uwsgi.lock_engine, "ipcsem")) { uwsgi_log_initial("lock engine: ipcsem\n"); atexit(uwsgi_ipcsem_clear); uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init; uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check; uwsgi.lock_ops.lock = uwsgi_lock_ipcsem; uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem; uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init; uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check; uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem; uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem; uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem; uwsgi.lock_size = 8; uwsgi.rwlock_size = 8; goto ready; } uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine); exit(1); } uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME); #ifdef UWSGI_IPCSEM_ATEXIT atexit(uwsgi_ipcsem_clear); #endif uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init; uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check; uwsgi.lock_ops.lock = uwsgi_lock_fast; uwsgi.lock_ops.unlock = uwsgi_unlock_fast; uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init; uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check; uwsgi.lock_ops.rlock = uwsgi_rlock_fast; uwsgi.lock_ops.wlock = uwsgi_wlock_fast; uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast; uwsgi.lock_size = UWSGI_LOCK_SIZE; uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE; ready: // application generic lock uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1)); for (i = 0; i < uwsgi.locks + 1; i++) { uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", uwsgi_num2str(i))); } // event queue lock (mitigate same event on multiple queues) if (uwsgi.threads > 1) { pthread_mutex_init(&uwsgi.thunder_mutex, NULL); } if (uwsgi.master_process) { // signal table lock uwsgi.signal_table_lock = uwsgi_lock_init("signal"); // fmon table lock uwsgi.fmon_table_lock = uwsgi_lock_init("filemon"); // timer table lock uwsgi.timer_table_lock = uwsgi_lock_init("timer"); // rb_timer table lock uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer"); // cron table lock uwsgi.cron_table_lock = uwsgi_lock_init("cron"); } if (uwsgi.use_thunder_lock) { // process shared thunder lock uwsgi.the_thunder_lock = uwsgi_lock_init("thunder"); } uwsgi.rpc_table_lock = uwsgi_lock_init("rpc"); #ifdef UWSGI_SSL // register locking for legions struct uwsgi_legion *ul = uwsgi.legions; while(ul) { ul->lock = uwsgi_lock_init(uwsgi_concat2("legion_", ul->legion)); ul = ul->next; } #endif uwsgi.locking_setup = 1; }
void uwsgi_ini_config(char *file, char *magic_table[]) { size_t len = 0; char *ini; char *ini_line; char *section = ""; char *key; char *val; int lines = 1; char *section_asked = "uwsgi"; char *colon; if (uwsgi_check_scheme(file)) { colon = uwsgi_get_last_char(file, '/'); colon = uwsgi_get_last_char(colon, ':'); } else { colon = uwsgi_get_last_char(file, ':'); } if (colon) { colon[0] = 0; if (colon[1] != 0) { section_asked = colon + 1; } } if (file[0] != 0) { uwsgi_log_initial("[uWSGI] getting INI configuration from %s\n", file); } ini = uwsgi_open_and_read(file, &len, 1, magic_table); while (len) { ini_line = ini_get_line(ini, len); if (ini_line == NULL) { break; } lines++; // skip empty line key = ini_lstrip(ini); ini_rstrip(key); if (key[0] != 0) { if (key[0] == '[') { section = key + 1; section[strlen(section) - 1] = 0; } else if (key[0] == ';' || key[0] == '#') { // this is a comment } else { // val is always valid, but (obviously) can be ignored val = ini_get_key(key); if (!strcmp(section, section_asked)) { ini_rstrip(key); val = ini_lstrip(val); ini_rstrip(val); add_exported_option((char *) key, val, 0); } } } len -= (ini_line - ini); ini += (ini_line - ini); } if (colon) { colon[0] = ':'; } }
void uwsgi_setup_locking() { int i; if (uwsgi.locking_setup) return; // use the fastest available locking if (uwsgi.lock_engine) { if (!strcmp(uwsgi.lock_engine, "ipcsem")) { uwsgi_log_initial("lock engine: ipcsem\n"); atexit(uwsgi_ipcsem_clear); uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init; uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check; uwsgi.lock_ops.lock = uwsgi_lock_ipcsem; uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem; uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init; uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check; uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem; uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem; uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem; uwsgi.lock_size = 8; uwsgi.rwlock_size = 8; goto ready; } uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine); exit(1); } uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME); #ifdef UWSGI_IPCSEM_ATEXIT atexit(uwsgi_ipcsem_clear); #endif uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init; uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check; uwsgi.lock_ops.lock = uwsgi_lock_fast; uwsgi.lock_ops.unlock = uwsgi_unlock_fast; uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init; uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check; uwsgi.lock_ops.rlock = uwsgi_rlock_fast; uwsgi.lock_ops.wlock = uwsgi_wlock_fast; uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast; uwsgi.lock_size = UWSGI_LOCK_SIZE; uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE; ready: // application generic lock uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1)); for (i = 0; i < uwsgi.locks + 1; i++) { char *num = uwsgi_num2str(i); uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", num)); free(num); } // event queue lock (mitigate same event on multiple queues) if (uwsgi.threads > 1) { pthread_mutex_init(&uwsgi.thunder_mutex, NULL); } if (uwsgi.master_process) { // signal table lock uwsgi.signal_table_lock = uwsgi_lock_init("signal"); // fmon table lock uwsgi.fmon_table_lock = uwsgi_lock_init("filemon"); // timer table lock uwsgi.timer_table_lock = uwsgi_lock_init("timer"); // rb_timer table lock uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer"); // cron table lock uwsgi.cron_table_lock = uwsgi_lock_init("cron"); } if (uwsgi.use_thunder_lock) { // process shared thunder lock uwsgi.the_thunder_lock = uwsgi_lock_init("thunder"); #ifdef UNBIT // we have a serious bug on Unbit (and very probably on older libc) // when all of the workers die in the same moment the pthread robust mutes is left // in inconsistent state and we have no way to recover // we span a thread in the master constantly ensuring the lock is ok // for now we apply it only for Unbit (where thunder-lock is automatically enabled) uwsgi_robust_mutexes_watchdog(); #endif } uwsgi.rpc_table_lock = uwsgi_lock_init("rpc"); #ifdef UWSGI_SSL // register locking for legions struct uwsgi_legion *ul = uwsgi.legions; while(ul) { ul->lock = uwsgi_lock_init(uwsgi_concat2("legion_", ul->legion)); ul = ul->next; } #endif uwsgi.locking_setup = 1; }
void uwsgi_json_config(char *file, char *magic_table[]) { size_t len = 0; char *json_data; const char *key; json_t *root; json_error_t error; json_t *config; json_t *config_value, *config_array_item; void *config_iter; char *object_asked = "uwsgi"; char *colon; int i; if (uwsgi_check_scheme(file)) { colon = uwsgi_get_last_char(file, '/'); colon = uwsgi_get_last_char(colon, ':'); } else { colon = uwsgi_get_last_char(file, ':'); } if (colon) { colon[0] = 0; if (colon[1] != 0) { object_asked = colon + 1; } } uwsgi_log_initial("[uWSGI] getting JSON configuration from %s\n", file); json_data = uwsgi_open_and_read(file, &len, 1, magic_table); #ifdef JANSSON_MAJOR_VERSION root = json_loads(json_data, 0, &error); #else root = json_loads(json_data, &error); #endif if (!root) { uwsgi_log("error parsing JSON data: line %d %s\n", error.line, error.text); exit(1); } config = json_object_get(root, object_asked); if (!json_is_object(config)) { uwsgi_log("you must define a object named %s in your JSON data\n", object_asked); exit(1); } config_iter = json_object_iter(config); while (config_iter) { key = json_object_iter_key(config_iter); config_value = json_object_iter_value(config_iter); if (json_is_string(config_value)) { add_exported_option((char *) key, (char *) json_string_value(config_value), 0); } else if (json_is_true(config_value)) { add_exported_option((char *) key, strdup("1"), 0); } else if (json_is_false(config_value) || json_is_null(config_value)) { add_exported_option((char *) key, strdup("0"), 0); } else if (json_is_integer(config_value)) { add_exported_option((char *) key, uwsgi_num2str(json_integer_value(config_value)), 0); } else if (json_is_array(config_value)) { for (i = 0; i < (int) json_array_size(config_value); i++) { config_array_item = json_array_get(config_value, i); if (json_is_string(config_array_item)) { add_exported_option((char *) key, (char *) json_string_value(config_array_item), 0); } else if (json_is_true(config_array_item)) { add_exported_option((char *) key, strdup("1"), 0); } else if (json_is_false(config_array_item) || json_is_null(config_array_item)) { add_exported_option((char *) key, strdup("0"), 0); } else if (json_is_integer(config_array_item)) { add_exported_option((char *) key, uwsgi_num2str(json_integer_value(config_array_item)), 0); } } } config_iter = json_object_iter_next(config, config_iter); } if (colon) colon[0] = ':'; }