void uwsgi_proto_zeromq_close(struct wsgi_request *wsgi_req) { zmq_msg_t reply; // check for already freed wsgi_req->proto_parser_buf/wsgi_req->proto_parser_pos if (!wsgi_req->proto_parser_pos) return; zmq_msg_init_data(&reply, wsgi_req->proto_parser_buf, wsgi_req->proto_parser_pos, uwsgi_proto_zeromq_free, NULL); if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.zmq_lock); if (zmq_send(uwsgi.zmq_pub, &reply, 0)) { uwsgi_error("zmq_send()"); } if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.zmq_lock); zmq_msg_close(&reply); if (wsgi_req->async_post && wsgi_req->body_as_file) { fclose(wsgi_req->async_post); } }
/* uwsgi ADMIN|10 */ int uwsgi_request_admin(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) { uint32_t opt_value = 0; int i; if (wsgi_req->uh.pktsize >= 4) { memcpy(&opt_value, &wsgi_req->buffer, 4); // TODO: check endianess } fprintf(stderr, "setting internal option %d to %d\n", wsgi_req->uh.modifier2, opt_value); uwsgi->shared->options[wsgi_req->uh.modifier2] = opt_value; wsgi_req->uh.modifier1 = 255; wsgi_req->uh.pktsize = 0; wsgi_req->uh.modifier2 = 1; i = write(wsgi_req->poll.fd, wsgi_req, 4); if (i != 4) { uwsgi_error("write()"); } return UWSGI_OK; }
// this is the event manager static void uwsgi_imperial_monitor_zeromq_event(struct uwsgi_emperor_scanner *ues) { for(;;) { uint32_t zmq_events = 0; size_t opt_len = sizeof(uint32_t); int ret = zmq_getsockopt(ues->data, ZMQ_EVENTS, &zmq_events, &opt_len); if (ret < 0) { uwsgi_error("zmq_getsockopt()"); return; } if (zmq_events & ZMQ_POLLIN) { uwsgi_imperial_monitor_zeromq_cmd(ues); continue; } break; } }
static int socket_send_metric(struct uwsgi_buffer *ub, struct uwsgi_stats_pusher_instance *uspi, struct uwsgi_metric *um) { struct socket_node *sn = (struct socket_node *) uspi->data; // reset the buffer ub->pos = 0; if (uwsgi_buffer_append(ub, sn->prefix, sn->prefix_len)) return -1; if (uwsgi_buffer_append(ub, ".", 1)) return -1; if (uwsgi_buffer_append(ub, um->name, um->name_len)) return -1; if (uwsgi_buffer_append(ub, " ", 1)) return -1; if (uwsgi_buffer_num64(ub, (int64_t) um->type)) return -1; if (uwsgi_buffer_append(ub, " ", 1)) return -1; if (uwsgi_buffer_num64(ub, *um->value)) return -1; if (sendto(sn->fd, ub->buf, ub->pos, 0, &sn->addr.sa, sn->addr_len) < 0) { if (errno != EAGAIN) // drop if we were to block uwsgi_error("socket_send_metric()/sendto()"); } return 0; }
static void spooler_scandir(struct uwsgi_spooler *uspool, char *dir) { struct dirent **tasklist; int n; if (!dir) dir = uspool->dir; n = scandir(dir, &tasklist, 0, versionsort); if (n < 0) { uwsgi_error("scandir()"); return; } while(n--) { spooler_manage_task(uspool, dir, tasklist[n]->d_name); free(tasklist[n]); } free(tasklist); }
void emperor_del(struct uwsgi_instance *c_ui) { struct uwsgi_instance *parent_ui = c_ui->ui_prev; struct uwsgi_instance *child_ui = c_ui->ui_next; parent_ui->ui_next = child_ui; if (child_ui) { child_ui->ui_prev = parent_ui; } // this will destroy the whole uWSGI instance (and workers) close(c_ui->pipe[0]); if (c_ui->use_config) { close(c_ui->pipe_config[0]); } if (uwsgi.vassals_stop_hook) { uwsgi_log("[emperor] running vassal stop-hook: %s %s\n", uwsgi.vassals_stop_hook, c_ui->name); if (uwsgi.emperor_absolute_dir) { if (setenv("UWSGI_VASSALS_DIR", uwsgi.emperor_absolute_dir, 1)) { uwsgi_error("setenv()"); } } int stop_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_stop_hook, c_ui->name); uwsgi_log("[emperor] %s stop-hook returned %d\n", c_ui->name, stop_hook_ret); } uwsgi_log("[emperor] removed uwsgi instance %s\n", c_ui->name); // put the instance in the blacklist (or update its throttling value) if (!c_ui->loyal) { uwsgi_emperor_blacklist_add(c_ui->name); } if (c_ui->zerg) { uwsgi.emperor_broodlord_count--; } free(c_ui); }
int uwsgi_simple_wait_write_hook(int fd, int timeout) { struct pollfd upoll; timeout = timeout * 1000; upoll.fd = fd; upoll.events = POLLOUT; upoll.revents = 0; int ret = poll(&upoll, 1, timeout); if (ret > 0) { if (upoll.revents & POLLOUT) { return 1; } return -1; } if (ret < 0) { uwsgi_error("uwsgi_simple_wait_write_hook()/poll()"); } return ret; }
static void spooler_scandir(struct uwsgi_spooler *uspool, char *dir) { struct dirent **tasklist; int n, i; if (!dir) dir = uspool->dir; n = scandir(dir, &tasklist, NULL, versionsort); if (n < 0) { uwsgi_error("scandir()"); return; } for (i = 0; i < n; i++) { spooler_manage_task(uspool, dir, tasklist[i]->d_name); free(tasklist[i]); } free(tasklist); }
int event_queue_wait(int eq, int timeout, int *interesting_fd) { int ret; struct epoll_event ee; if (timeout > 0) { timeout = timeout*1000; } ret = epoll_wait(eq, &ee, 1, timeout); if (ret < 0) { if (errno != EINTR) uwsgi_error("epoll_wait()"); } if (ret > 0) { *interesting_fd = ee.data.fd; } return ret; }
int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) { int ret; struct timespec ts; if (timeout < 0) { ret = kevent(eq, NULL, 0, events, nevents, NULL); } else { memset(&ts, 0, sizeof(struct timespec)); ts.tv_sec = timeout; ret = kevent(eq, NULL, 0, (struct kevent *)events, nevents, &ts); } if (ret < 0) { uwsgi_error("kevent()"); } return ret; }
int connect_to_tcp(char *socket_name, int port, int timeout, int async) { struct pollfd uwsgi_poll; struct sockaddr_in uws_addr; memset(&uws_addr, 0, sizeof(struct sockaddr_in)); uws_addr.sin_family = AF_INET; uws_addr.sin_port = htons(port); if (socket_name[0] == 0) { uws_addr.sin_addr.s_addr = INADDR_ANY; } else { uws_addr.sin_addr.s_addr = inet_addr(socket_name); } socket_name[strlen(socket_name)] = ':'; #if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL) uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); #else uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM, 0); #endif if (uwsgi_poll.fd < 0) { uwsgi_error("socket()"); return -1; } uwsgi_poll.events = POLLIN; if (timed_connect(&uwsgi_poll, (const struct sockaddr *) &uws_addr, sizeof(struct sockaddr_in), timeout, async)) { //uwsgi_error("connect()"); close(uwsgi_poll.fd); return -1; } return uwsgi_poll.fd; }
int connect_to_unix(char *socket_name, int timeout, int async) { struct pollfd uwsgi_poll; struct sockaddr_un uws_addr; socklen_t un_size = sizeof(struct sockaddr_un); memset(&uws_addr, 0, sizeof(struct sockaddr_un)); uws_addr.sun_family = AF_UNIX; if (socket_name[0] == '@') { un_size = sizeof(uws_addr.sun_family) + strlen(socket_name) + 1; memcpy(uws_addr.sun_path + 1, socket_name + 1, UMIN(strlen(socket_name + 1), 101)); } else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') { un_size = sizeof(uws_addr.sun_family) + strlen(socket_name + 1) + 1; memcpy(uws_addr.sun_path + 1, socket_name + 2, UMIN(strlen(socket_name + 2), 101)); } else { memcpy(uws_addr.sun_path, socket_name, UMIN(strlen(socket_name), 102)); } uwsgi_poll.fd = socket(AF_UNIX, SOCK_STREAM, 0); if (uwsgi_poll.fd < 0) { uwsgi_error("socket()"); return -1; } uwsgi_poll.events = POLLIN; if (timed_connect(&uwsgi_poll, (const struct sockaddr *) &uws_addr, un_size, timeout, async)) { // avoid error storm //uwsgi_error("connect()"); close(uwsgi_poll.fd); return -1; } return uwsgi_poll.fd; }
void uwsgi_opt_add_spooler(char *opt, char *directory, void *mode) { int i; struct uwsgi_spooler *us; if (access(directory, R_OK | W_OK | X_OK)) { uwsgi_error("[spooler directory] access()"); exit(1); } if (uwsgi.spooler_numproc > 0) { for(i=0; i<uwsgi.spooler_numproc; i++) { us = uwsgi_new_spooler(directory); if (mode) us->mode = (long) mode; } } else { us = uwsgi_new_spooler(directory); if (mode) us->mode = (long) mode; } }
void uwsgi_lock_ipcsem(struct uwsgi_lock_item *uli) { int semid; struct sembuf sb; sb.sem_num = 0; sb.sem_op = -1; sb.sem_flg = SEM_UNDO; memcpy(&semid, uli->lock_ptr, sizeof(int)); retry: if (semop(semid, &sb, 1)) { if (errno == EINTR) goto retry; uwsgi_error("uwsgi_lock_ipcsem()/semop()"); #ifdef EIDRM if (errno == EIDRM) { exit(UWSGI_BRUTAL_RELOAD_CODE); } #endif exit(1); } }
int uwsgi_hooks_run_and_return(struct uwsgi_string_list *l, char *phase, char *context, int fatal) { int final_ret = 0; struct uwsgi_string_list *usl = NULL; if (context) { if (setenv("UWSGI_HOOK_CONTEXT", context, 1)) { uwsgi_error("uwsgi_hooks_run_and_return()/setenv()"); return -1; } } uwsgi_foreach(usl, l) { char *colon = strchr(usl->value, ':'); if (!colon) { uwsgi_log("invalid hook syntax, must be hook:args\n"); exit(1); } *colon = 0; int private = 0; char *action = usl->value; // private hook ? if (action[0] == '!') { action++; private = 1;
static void ping() { struct uwsgi_header uh; char *buf = NULL; // use a 3 secs timeout by default if (!uping.ping_timeout) uping.ping_timeout = 3; uwsgi_log("PING uwsgi host %s (timeout: %d)\n", uping.ping, uping.ping_timeout); int fd = uwsgi_connect(uping.ping, uping.ping_timeout, 0); if (fd < 0) { exit(1); } uh.modifier1 = UWSGI_MODIFIER_PING; uh.pktsize = 0; uh.modifier2 = 0; if (write(fd, &uh, 4) != 4) { uwsgi_error("write()"); exit(2); } int ret = uwsgi_read_response(fd, &uh, uping.ping_timeout, &buf); if (ret < 0) { exit(1); } else { if (uh.pktsize > 0) { uwsgi_log("[WARNING] node %s message: %.*s\n", uping.ping, uh.pktsize, buf); exit(2); } else { exit(0); } } }
int event_queue_add_file_monitor(int eq, char *filename, int *id) { struct kevent kev; int fd = open(filename, O_RDONLY); if (fd < 0) { uwsgi_error_open(filename); return -1; } EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE|NOTE_DELETE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_RENAME|NOTE_REVOKE, 0, 0); if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) { uwsgi_error("kevent()"); return -1; } *id = fd; uwsgi_log("added new file to monitor %s\n", filename); return fd; }
static int uwsgi_hook_chown(char *arg) { char *space = strchr(arg, ' '); if (!space) { uwsgi_log("invalid hook chown syntax, must be: <file> <uid> <gid>\n"); return -1; } *space = 0; char *space2 = strchr(space+1, ' '); if (!space2) { *space = ' '; uwsgi_log("invalid hook chown syntax, must be: <file> <uid> <gid>\n"); return -1; } *space2 = 0; struct passwd *pw = getpwnam(space+1); if (!pw) { uwsgi_log("unable to find uid %s\n", space+1); *space = ' '; *space2 = ' '; return -1; } struct group *gr = getgrnam(space2+1); if (!gr) { uwsgi_log("unable to find gid %s\n", space2+1); *space = ' '; *space2 = ' '; return -1; } int ret = chown(arg, pw->pw_uid, gr->gr_gid); *space = ' '; *space2 = ' '; if (ret) { uwsgi_error("uwsgi_hook_chown()/chown)"); } return ret; }
static int uwsgi_hook_chmod(char *arg) { char *space = strchr(arg, ' '); if (!space) { uwsgi_log("invalid hook chmod syntax, must be: <file> <mode>\n"); return -1; } *space = 0; int error = 0; mode_t mask = uwsgi_mode_t(space+1, &error); if (error) { uwsgi_log("invalid hook chmod mask: %s\n", space+1); *space = ' '; return -1; } int ret = chmod(arg, mask); *space = ' '; if (ret) { uwsgi_error("uwsgi_hook_chmod()/chmod()"); } return ret; }
static void uwsgi_offload_loop(struct uwsgi_thread *ut) { int i; void *events = event_queue_alloc(uwsgi.offload_threads_events); for (;;) { // TODO make timeout tunable int nevents = event_queue_wait_multi(ut->queue, -1, events, uwsgi.offload_threads_events); for (i = 0; i < nevents; i++) { int interesting_fd = event_queue_interesting_fd(events, i); if (interesting_fd == ut->pipe[1]) { struct uwsgi_offload_request *uor = uwsgi_malloc(sizeof(struct uwsgi_offload_request)); ssize_t len = read(ut->pipe[1], uor, sizeof(struct uwsgi_offload_request)); if (len != sizeof(struct uwsgi_offload_request)) { uwsgi_error("read()"); free(uor); continue; } // cal the event function for the first time if (uor->engine->event_func(ut, uor, -1)) { uwsgi_offload_close(ut, uor); continue; } uwsgi_offload_append(ut, uor); continue; } // get the task from the interesting fd struct uwsgi_offload_request *uor = uwsgi_offload_get_by_fd(ut, interesting_fd); if (!uor) continue; // run the hook if (uor->engine->event_func(ut, uor, interesting_fd)) { uwsgi_offload_close(ut, uor); } } } }
struct uwsgi_gateway *register_gateway(char *name, void (*loop)(int, void *), void *data) { struct uwsgi_gateway *ug; int num=1,i; if (ushared->gateways_cnt >= MAX_GATEWAYS) { uwsgi_log("you can register max %d gateways\n", MAX_GATEWAYS); return NULL; } for(i=0;i<ushared->gateways_cnt;i++) { if (!strcmp(name, ushared->gateways[i].name)) { num++; } } char *fullname = uwsgi_concat3(name, " ", uwsgi_num2str(num)); ug = &ushared->gateways[ushared->gateways_cnt]; ug->pid = 0; ug->name = name; ug->loop = loop; ug->num = num; ug->fullname = fullname; ug->data = data; if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ug->internal_subscription_pipe)) { uwsgi_error("socketpair()"); } if (!uwsgi.master_process) gateway_respawn(ushared->gateways_cnt); ushared->gateways_cnt++; return ug; }
static int uwsgi_hook_chown2(char *arg) { char *space = strchr(arg, ' '); if (!space) { uwsgi_log("invalid hook chown2 syntax, must be: <file> <uid> <gid>\n"); return -1; } *space = 0; char *space2 = strchr(space+1, ' '); if (!space2) { *space = ' '; uwsgi_log("invalid hook chown2 syntax, must be: <file> <uid> <gid>\n"); return -1; } *space2 = 0; if (!is_a_number(space+1)) { uwsgi_log("invalid hook chown2 syntax, uid must be a number\n"); *space = ' '; *space2 = ' '; return -1; } if (!is_a_number(space2+1)) { uwsgi_log("invalid hook chown2 syntax, gid must be a number\n"); *space = ' '; *space2 = ' '; return -1; } int ret = chown(arg, atoi(space+1), atoi(space2+1)); *space = ' '; *space2 = ' '; if (ret) { uwsgi_error("uwsgi_hook_chown2()/chown)"); } return ret; }
struct uwsgi_timer *event_queue_ack_timer(int id) { int i; ssize_t rlen; uint64_t counter; struct uwsgi_timer *ut = NULL; for(i=0;i<ushared->timers_cnt;i++) { if (ushared->timers[i].registered) { if (ushared->timers[i].id == id) { ut = &ushared->timers[i]; } } } rlen = read(id, &counter, sizeof(uint64_t)); if (rlen < 0) { uwsgi_error("read()"); } return ut; }
int uwsgi_remote_signal_send(char *addr, uint8_t sig) { struct uwsgi_header uh; uh.modifier1 = 110; uh.pktsize = 0; uh.modifier2 = sig; int fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0); if (fd < 0) return -1; if (write(fd, (char *) &uh, 4) != 4) { uwsgi_error("uwsgi_remote_signal_send()"); close(fd); return -1; } int ret = uwsgi_read_response(fd, &uh, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], NULL); close(fd); return ret; }
static int uwsgi_hook_append(char *arg) { char *space = strchr(arg, ' '); if (!space) { uwsgi_log("invalid hook append syntax, must be: <file> <string>\n"); return -1; } *space = 0; int fd = open(arg, O_WRONLY|O_CREAT|O_APPEND, 0666); if (fd < 0) { uwsgi_error_open(arg); *space = ' '; return -1; } *space = ' '; size_t l = strlen(space+1); if (write(fd, space+1, l) != (ssize_t) l) { uwsgi_error("uwsgi_hook_append()/write()"); close(fd); return -1; } close(fd); return 0; }
ssize_t hr_ssl_write(struct corerouter_peer *main_peer) { struct corerouter_session *cs = main_peer->session; struct http_session *hr = (struct http_session *) cs; int ret = SSL_write(hr->ssl, main_peer->out->buf + main_peer->out_pos, main_peer->out->pos - main_peer->out_pos); if (ret > 0) { main_peer->out_pos += ret; if (main_peer->out->pos == main_peer->out_pos) { // reset the buffer (if needed) main_peer->out->pos = 0; cr_reset_hooks(main_peer); } return ret; } if (ret == 0) return 0; int err = SSL_get_error(hr->ssl, ret); if (err == SSL_ERROR_WANT_READ) { cr_reset_hooks_and_read(main_peer, hr_ssl_write); return 1; } else if (err == SSL_ERROR_WANT_WRITE) { cr_write_to_main(main_peer, hr_ssl_write); return 1; } else if (err == SSL_ERROR_SYSCALL) { uwsgi_error("hr_ssl_write()"); } else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) { ERR_print_errors_fp(stderr); } return -1; }
ssize_t uwsgi_proto_zeromq_write(struct wsgi_request * wsgi_req, char *buf, size_t len) { zmq_msg_t reply; char *zmq_body; if (len == 0) return 0; zmq_body = uwsgi_concat2n(wsgi_req->proto_parser_buf, (int) wsgi_req->proto_parser_pos, buf, (int) len); //uwsgi_log("|%.*s|\n", (int)wsgi_req->proto_parser_pos+len, zmq_body); zmq_msg_init_data(&reply, zmq_body, wsgi_req->proto_parser_pos + len, uwsgi_proto_zeromq_free, NULL); if (uwsgi.threads > 1) pthread_mutex_lock(&uwsgi.zmq_lock); if (zmq_send(uwsgi.zmq_pub, &reply, 0)) { uwsgi_error("zmq_send()"); if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.zmq_lock); zmq_msg_close(&reply); return -1; } if (uwsgi.threads > 1) pthread_mutex_unlock(&uwsgi.zmq_lock); zmq_msg_close(&reply); return len; }
void uwsgi_master_restore_snapshot() { int i, waitpid_status; uwsgi_log("[snapshot] restoring workers...\n"); for (i = 1; i <= uwsgi.numproc; i++) { if (uwsgi.workers[i].pid == 0) continue; kill(uwsgi.workers[i].pid, SIGKILL); if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) { uwsgi_error("waitpid()"); } if (uwsgi.auto_snapshot > 0 && i > uwsgi.auto_snapshot) { uwsgi.workers[i].pid = 0; uwsgi.workers[i].snapshot = 0; } else { uwsgi.workers[i].pid = uwsgi.workers[i].snapshot; uwsgi.workers[i].snapshot = 0; kill(uwsgi.workers[i].pid, SIGURG); uwsgi_log("Restored uWSGI worker %d (pid: %d)\n", i, (int) uwsgi.workers[i].pid); } } uwsgi.restore_snapshot = 0; }
PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) { #ifdef UWSGI_PYPY uwsgi_log("import by filename is currently not supported on PyPy !!!\n"); return NULL; #else FILE *pyfile; struct _node *py_file_node = NULL; PyObject *py_compiled_node, *py_file_module; int is_a_package = 0; struct stat pystat; char *real_filename = filename; if (!uwsgi_check_scheme(filename)) { pyfile = fopen(filename, "r"); if (!pyfile) { uwsgi_log("failed to open python file %s\n", filename); return NULL; } if (fstat(fileno(pyfile), &pystat)) { uwsgi_error("fstat()"); return NULL; } if (S_ISDIR(pystat.st_mode)) { is_a_package = 1; fclose(pyfile); real_filename = uwsgi_concat2(filename, "/__init__.py"); pyfile = fopen(real_filename, "r"); if (!pyfile) { uwsgi_error_open(real_filename); free(real_filename); return NULL; } } py_file_node = PyParser_SimpleParseFile(pyfile, real_filename, Py_file_input); if (!py_file_node) { PyErr_Print(); uwsgi_log("failed to parse file %s\n", real_filename); if (is_a_package) free(real_filename); fclose(pyfile); return NULL; } fclose(pyfile); } else { int pycontent_size = 0; char *pycontent = uwsgi_open_and_read(filename, &pycontent_size, 1, NULL); if (pycontent) { py_file_node = PyParser_SimpleParseString(pycontent, Py_file_input); if (!py_file_node) { PyErr_Print(); uwsgi_log("failed to parse url %s\n", real_filename); return NULL; } } } py_compiled_node = (PyObject *) PyNode_Compile(py_file_node, real_filename); if (!py_compiled_node) { PyErr_Print(); uwsgi_log("failed to compile python file %s\n", real_filename); return NULL; } if (is_a_package) { py_file_module = PyImport_AddModule(name); if (py_file_module) { PyModule_AddObject(py_file_module, "__path__", Py_BuildValue("[O]", PyString_FromString(filename))); } free(real_filename); } py_file_module = PyImport_ExecCodeModule(name, py_compiled_node); if (!py_file_module) { PyErr_Print(); return NULL; } Py_DECREF(py_compiled_node); return py_file_module; #endif }
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; }