diff --git a/core/cluster.c b/core/cluster.c index ddb8e2a1..314fa5e1 100644 --- a/core/cluster.c +++ b/core/cluster.c @@ -363,23 +363,23 @@ void manage_cluster_message(char *cluster_opt_buf, int cluster_opt_size) { struct uwsgi_cluster_node nucn; - switch (uwsgi.wsgi_requests[0]->uh.modifier1) { + switch (uwsgi.workers[0].cores[0].req.uh.modifier1) { case 95: memset(&nucn, 0, sizeof(struct uwsgi_cluster_node)); #ifdef __BIG_ENDIAN__ - uwsgi.wsgi_requests[0]->uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize); + uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize); #endif - uwsgi_hooked_parse(uwsgi.wsgi_requests[0]->buffer, uwsgi.wsgi_requests[0]->uh.pktsize, manage_cluster_announce, &nucn); + uwsgi_hooked_parse(uwsgi.workers[0].cores[0].req.buffer, uwsgi.workers[0].cores[0].req.uh.pktsize, manage_cluster_announce, &nucn); if (nucn.name[0] != 0) { uwsgi_cluster_add_node(&nucn, CLUSTER_NODE_DYNAMIC); } break; case 96: #ifdef __BIG_ENDIAN__ - uwsgi.wsgi_requests[0]->uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize); + uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize); #endif - uwsgi_log_verbose("%.*s\n", uwsgi.wsgi_requests[0]->uh.pktsize, uwsgi.wsgi_requests[0]->buffer); + uwsgi_log_verbose("%.*s\n", uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer); break; case 98: if (kill(getpid(), SIGHUP)) { @@ -389,16 +389,16 @@ void manage_cluster_message(char *cluster_opt_buf, int cluster_opt_size) { case 99: if (uwsgi.cluster_nodes) break; - if (uwsgi.wsgi_requests[0]->uh.modifier2 == 0) { + if (uwsgi.workers[0].cores[0].req.uh.modifier2 == 0) { uwsgi_log("requested configuration data, sending %d bytes\n", cluster_opt_size); sendto(uwsgi.cluster_fd, cluster_opt_buf, cluster_opt_size, 0, (struct sockaddr *) &uwsgi.mc_cluster_addr, sizeof(uwsgi.mc_cluster_addr)); } break; case 73: #ifdef __BIG_ENDIAN__ - uwsgi.wsgi_requests[0]->uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->uh.pktsize); + uwsgi.workers[0].cores[0].req.uh.pktsize = uwsgi_swap16(uwsgi.workers[0].cores[0].req.uh.pktsize); #endif - uwsgi_log_verbose("[uWSGI cluster %s] new node available: %.*s\n", uwsgi.cluster, uwsgi.wsgi_requests[0]->uh.pktsize, uwsgi.wsgi_requests[0]->buffer); + uwsgi_log_verbose("[uWSGI cluster %s] new node available: %.*s\n", uwsgi.cluster, uwsgi.workers[0].cores[0].req.uh.pktsize, uwsgi.workers[0].cores[0].req.buffer); break; } } diff --git a/core/loop.c b/core/loop.c index 9aa25dae..7d3cef90 100644 --- a/core/loop.c +++ b/core/loop.c @@ -39,7 +39,7 @@ void *simple_loop(void *arg1) { long core_id = (long) arg1; - struct wsgi_request *wsgi_req = uwsgi.wsgi_requests[core_id]; + struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core_id].req; #ifdef UWSGI_THREADING int i; diff --git a/core/master.c b/core/master.c index 29dbf831..2a92bc96 100644 --- a/core/master.c +++ b/core/master.c @@ -1031,7 +1031,7 @@ int master_loop(char **argv, char **environ) { #ifdef UWSGI_MULTICAST if (interesting_fd == uwsgi.cluster_fd) { - if (uwsgi_get_dgram(uwsgi.cluster_fd, uwsgi.wsgi_requests[0])) { + if (uwsgi_get_dgram(uwsgi.cluster_fd, &uwsgi.workers[0].cores[0].req)) { goto health_cycle; } diff --git a/core/utils.c b/core/utils.c index 6bbf6ea3..1b023c5f 100644 --- a/core/utils.c +++ b/core/utils.c @@ -1000,7 +1000,7 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id, struct uwsgi_so wsgi_req->socket = uwsgi_sock; } - uwsgi.core[wsgi_req->async_id]->in_request = 0; + uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 0; uwsgi.workers[uwsgi.mywid].busy = 0; // now check for suspend request @@ -1018,7 +1018,7 @@ cycle: #ifdef UWSGI_ASYNC int wsgi_req_async_recv(struct wsgi_request *wsgi_req) { - uwsgi.core[wsgi_req->async_id]->in_request = 1; + uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1; uwsgi.workers[uwsgi.mywid].busy = 1; gettimeofday(&wsgi_req->start_of_request, NULL); @@ -1044,7 +1044,7 @@ int wsgi_req_async_recv(struct wsgi_request *wsgi_req) { int wsgi_req_recv(struct wsgi_request *wsgi_req) { - uwsgi.core[wsgi_req->async_id]->in_request = 1; + uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1; uwsgi.workers[uwsgi.mywid].busy = 1; gettimeofday(&wsgi_req->start_of_request, NULL); @@ -3312,6 +3312,12 @@ void *uwsgi_malloc_shared(size_t size) { return addr; } +void *uwsgi_calloc_shared(size_t size) { + void *ptr = uwsgi_malloc_shared(size); + memset(ptr, 0, size); + return ptr; +} + struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list, char *value) { @@ -4230,6 +4236,11 @@ char *uwsgi_get_var(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, u struct uwsgi_app *uwsgi_add_app(int id, uint8_t modifier1, char *mountpoint, int mountpoint_len, void *interpreter, void *callable) { + if (id > uwsgi.max_apps) { + uwsgi_log("FATAL ERROR: you cannot load more than %d apps in a worker\n", uwsgi.max_apps); + exit(1); + } + struct uwsgi_app *wi = &uwsgi_apps[id]; memset(wi, 0, sizeof(struct uwsgi_app)); diff --git a/core/uwsgi.c b/core/uwsgi.c index ab41ecc6..0a762c14 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -105,6 +105,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"listen", required_argument, 'l', "set the socket listen queue size", uwsgi_opt_set_int, &uwsgi.listen_queue, 0}, {"max-vars", required_argument, 'v', "set the amount of internal iovec/vars structures", uwsgi_opt_max_vars, NULL, 0}, + {"max-apps", required_argument, 0, "set the maximum number of per-worker applications", uwsgi_opt_set_int, &uwsgi.max_apps, 0}, {"buffer-size", required_argument, 'b', "set internal buffer size", uwsgi_opt_set_int, &uwsgi.buffer_size, 0}, {"memory-report", no_argument, 'm', "enable memory report", uwsgi_opt_dyn_true, (void *) UWSGI_OPTION_MEMORY_DEBUG, 0}, {"profiler", required_argument, 0, "enable the specified profiler", uwsgi_opt_set_str, &uwsgi.profiler, 0}, @@ -382,10 +383,10 @@ static struct uwsgi_option uwsgi_base_options[] = { {"cheaper-list", no_argument, 0, "list enabled cheapers algorithms", uwsgi_opt_true, &uwsgi.cheaper_algo_list, 0}, {"idle", required_argument, 0, "set idle mode (put uWSGI in cheap mode after inactivity)", uwsgi_opt_set_int, &uwsgi.idle, UWSGI_OPT_MASTER}, {"die-on-idle", no_argument, 0, "shutdown uWSGI when idle", uwsgi_opt_true, &uwsgi.die_on_idle, 0}, - {"mount", required_argument, 0, "load application under mountpoint", uwsgi_opt_add_app, NULL, 0}, - {"worker-mount", required_argument, 0, "load application under mountpoint in the specified worker or after workers spawn", uwsgi_opt_add_app, NULL, 0}, + {"mount", required_argument, 0, "load application under mountpoint", uwsgi_opt_add_string_list, &uwsgi.mounts, 0}, + {"worker-mount", required_argument, 0, "load application under mountpoint in the specified worker or after workers spawn", uwsgi_opt_add_string_list, &uwsgi.mounts, 0}, #ifdef UWSGI_PCRE - {"regexp-mount", required_argument, 0, "load application under a regexp-based mountpoint", uwsgi_opt_add_app, NULL, 0}, + {"regexp-mount", required_argument, 0, "load application under a regexp-based mountpoint", uwsgi_opt_add_string_list, &uwsgi.mounts, 0}, #endif {"grunt", no_argument, 0, "enable grunt mode (in-request fork)", uwsgi_opt_true, &uwsgi.grunt, 0}, @@ -698,8 +699,8 @@ void wait_for_threads() { pthread_mutex_lock(&uwsgi.six_feet_under_lock); for (i = 0; i < uwsgi.threads; i++) { - if (!pthread_equal(uwsgi.core[i]->thread_id, pthread_self())) { - if (pthread_cancel(uwsgi.core[i]->thread_id)) { + if (!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, pthread_self())) { + if (pthread_cancel(uwsgi.workers[uwsgi.mywid].cores[i].thread_id)) { uwsgi_error("pthread_cancel()\n"); sudden_death = 1; } @@ -711,8 +712,8 @@ void wait_for_threads() { // wait for thread termination for (i = 0; i < uwsgi.threads; i++) { - if (!pthread_equal(uwsgi.core[i]->thread_id, pthread_self())) { - ret = pthread_join(uwsgi.core[i]->thread_id, NULL); + if (!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, pthread_self())) { + ret = pthread_join(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, NULL); if (ret) { uwsgi_log("pthread_join() = %d\n", ret); } @@ -734,7 +735,7 @@ void gracefully_kill(int signum) { if (uwsgi.threads > 1) { struct wsgi_request *wsgi_req = current_wsgi_req(); wait_for_threads(); - if (!uwsgi.core[wsgi_req->async_id]->in_request) { + if (!uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request) { exit(UWSGI_RELOAD_CODE); } return; @@ -747,7 +748,7 @@ void gracefully_kill(int signum) { exit(UWSGI_RELOAD_CODE); } - if (!uwsgi.core[0]->in_request) { + if (!uwsgi.workers[uwsgi.mywid].cores[0].in_request) { exit(UWSGI_RELOAD_CODE); } } @@ -1090,7 +1091,7 @@ void what_i_am_doing() { if (uwsgi.cores > 1) { for (i = 0; i < uwsgi.cores; i++) { - wsgi_req = uwsgi.wsgi_requests[i]; + wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[i].req; if (wsgi_req->uri_len > 0) { #ifdef __sun__ ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, ctime_storage, 26); @@ -1107,7 +1108,7 @@ void what_i_am_doing() { } } else { - wsgi_req = uwsgi.wsgi_requests[0]; + wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[0].req; if (wsgi_req->uri_len > 0) { #ifdef __sun__ ctime_r((const time_t *) &wsgi_req->start_of_request.tv_sec, ctime_storage, 26); @@ -1604,6 +1605,7 @@ int main(int argc, char *argv[], char *envp[]) { } uwsgi.backtrace_depth = 64; + uwsgi.max_apps = 64; uwsgi.master_queue = -1; @@ -2432,13 +2434,6 @@ int uwsgi_start(void *v_argv) { uwsgi_log_initial("detected max file descriptor number: %d\n", (int) uwsgi.max_fd); } - uwsgi.wsgi_requests = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.cores); - - for (i = 0; i < uwsgi.cores; i++) { - uwsgi.wsgi_requests[i] = uwsgi_malloc(sizeof(struct wsgi_request)); - memset(uwsgi.wsgi_requests[i], 0, sizeof(struct wsgi_request)); - } - uwsgi.async_buf = uwsgi_malloc(sizeof(char *) * uwsgi.cores); if (uwsgi.async > 1) { @@ -2468,12 +2463,10 @@ int uwsgi_start(void *v_argv) { uwsgi_log("cores allocated...\n"); #endif - //by default set wsgi_req to the first slot - uwsgi.wsgi_req = uwsgi.wsgi_requests[0]; - if (uwsgi.cores > 1) { - uwsgi_log("allocated %llu bytes (%llu KB) for %d cores per worker.\n", (uint64_t) (sizeof(struct wsgi_request) * uwsgi.cores), (uint64_t) ((sizeof(struct wsgi_request) * uwsgi.cores) / 1024), uwsgi.cores); + uwsgi_log("allocated %llu bytes (%llu KB) for %d cores per worker.\n", (uint64_t) (sizeof(struct uwsgi_core) * uwsgi.cores), (uint64_t) ((sizeof(struct uwsgi_core) * uwsgi.cores) / 1024), uwsgi.cores); } + if (uwsgi.vhost) { uwsgi_log("VirtualHosting mode enabled.\n"); } @@ -2867,17 +2860,22 @@ nextsock: - // apps are now per-worker - //memset(uwsgi.apps, 0, sizeof(uwsgi.apps)); + // allocate shared memory for workers + master + uwsgi.workers = (struct uwsgi_worker *) uwsgi_calloc_shared(sizeof(struct uwsgi_worker) * (uwsgi.numproc + 1 + uwsgi.grunt)); - uwsgi.workers = (struct uwsgi_worker *) mmap(NULL, sizeof(struct uwsgi_worker) * (uwsgi.numproc + 1 + uwsgi.grunt), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); - if (!uwsgi.workers) { - uwsgi_error("mmap()"); - exit(1); - } - memset(uwsgi.workers, 0, sizeof(struct uwsgi_worker) * uwsgi.numproc + 1); + for (i = 0; i <= uwsgi.numproc; i++) { + // allocate memory for apps + uwsgi.workers[i].apps = (struct uwsgi_app *) uwsgi_calloc_shared(sizeof(struct uwsgi_app) * uwsgi.max_apps); - for (i = 1; i <= uwsgi.numproc; i++) { + // allocate memory for cores + uwsgi.workers[i].cores = (struct uwsgi_core *) uwsgi_calloc_shared(sizeof(struct uwsgi_core) * uwsgi.cores); + + // allocate shared memory for thread states (required for some language, like python) + for (j = 0; j < uwsgi.cores; j++) { + uwsgi.workers[i].cores[j].ts = uwsgi_calloc_shared(sizeof(void *) * uwsgi.max_apps); + } + // master does not need to following steps... + if (i == 0) continue; uwsgi.workers[i].signal_pipe[0] = -1; uwsgi.workers[i].signal_pipe[1] = -1; snprintf(uwsgi.workers[i].name, 0xff, "uWSGI worker %d", i); @@ -2996,14 +2994,10 @@ nextsock: uwsgi_log("*** Operational MODE: single process ***\n"); } - // even the master has cores.. - uwsgi.core = uwsgi_malloc(sizeof(struct uwsgi_core *) * uwsgi.cores); - for (j = 0; j < uwsgi.cores; j++) { - uwsgi.core[j] = uwsgi_malloc(sizeof(struct uwsgi_core)); - memset(uwsgi.core[j], 0, sizeof(struct uwsgi_core)); - } + // set a default request structure (for loading apps...) + uwsgi.wsgi_req = &uwsgi.workers[0].cores[0].req; - // cores are now allocated, lets allocate logformat (if required) + // cores are allocated, lets allocate logformat (if required) if (uwsgi.logformat) { uwsgi_build_log_format(uwsgi.logformat); uwsgi.logit = uwsgi_logit_lf; @@ -3338,6 +3332,16 @@ nextsock: if (uwsgi.master_as_root) { uwsgi_as_root(); } + + // set default wsgi_req (for loading apps); + uwsgi.wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[0].req; + + // must be run before running apps + for (i = 0; i < 256; i++) { + if (uwsgi.p[i]->post_fork) { + uwsgi.p[i]->post_fork(); + } + } if (uwsgi.lazy || uwsgi.lazy_apps) { uwsgi_init_all_apps(); @@ -3345,11 +3349,6 @@ nextsock: uwsgi_init_worker_mount_apps(); - for (i = 0; i < 256; i++) { - if (uwsgi.p[i]->post_fork) { - uwsgi.p[i]->post_fork(); - } - } #ifdef UWSGI_ZEROMQ // setup zeromq context (if required) one per-worker @@ -3389,7 +3388,7 @@ zmq_next: uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.async); for (i = 0; i < uwsgi.async; i++) { - uwsgi.async_queue_unused[i] = uwsgi.wsgi_requests[i]; + uwsgi.async_queue_unused[i] = &uwsgi.workers[uwsgi.mywid].cores[i].req; } uwsgi.async_queue_unused_ptr = uwsgi.async - 1; @@ -3440,8 +3439,8 @@ zmq_next: //re - initialize wsgi_req(can be full of init_uwsgi_app data) for (i = 0; i < uwsgi.cores; i++) { - memset(uwsgi.wsgi_requests[i], 0, sizeof(struct wsgi_request)); - uwsgi.wsgi_requests[i]->async_id = i; + memset(&uwsgi.workers[uwsgi.mywid].cores[i].req, 0, sizeof(struct wsgi_request)); + uwsgi.workers[uwsgi.mywid].cores[i].req.async_id = i; } @@ -3464,7 +3463,7 @@ zmq_next: #ifdef UWSGI_THREADING if (uwsgi.cores > 1) { - uwsgi.core[0]->thread_id = pthread_self(); + uwsgi.workers[uwsgi.mywid].cores[0].thread_id = pthread_self(); pthread_mutex_init(&uwsgi.six_feet_under_lock, NULL); } #endif @@ -3524,7 +3523,7 @@ wait_for_call_of_duty: } for (i = 1; i < uwsgi.threads; i++) { long j = i; - pthread_create(&uwsgi.core[i]->thread_id, &uwsgi.threads_attr, simple_loop, (void *) j); + pthread_create(&uwsgi.workers[uwsgi.mywid].cores[i].thread_id, &uwsgi.threads_attr, simple_loop, (void *) j); } #endif } @@ -3773,14 +3772,18 @@ void uwsgi_init_all_apps() { } } - for (i = 0; i < uwsgi.mounts_cnt; i++) { - char *what = strchr(uwsgi.mounts[i], '='); + uwsgi_log("APPS COUNT %d\n", uwsgi_apps_cnt); + + struct uwsgi_string_list *app_mps = uwsgi.mounts; + while(app_mps) { + char *what = strchr(app_mps->value, '='); if (what) { what[0] = 0; what++; for (j = 0; j < 256; j++) { if (uwsgi.p[j]->mount_app) { - if (!uwsgi_startswith(uwsgi.mounts[i], "regexp://", 9)) { +/* + if (!uwsgi_startswith(uwsgin[i], "regexp://", 9)) { uwsgi_log("mounting %s on %s\n", what, uwsgi.mounts[i]+9); if (uwsgi.p[j]->mount_app(uwsgi.mounts[i] + 9, what, 1) != -1) break; @@ -3790,19 +3793,20 @@ void uwsgi_init_all_apps() { continue; } else { - uwsgi_log("mounting %s on %s\n", what, uwsgi.mounts[i]); - if (uwsgi.p[j]->mount_app(uwsgi.mounts[i], what, 0) != -1) - break; - } +*/ + uwsgi_log("mounting %s on %s\n", what, app_mps->value); + if (uwsgi.p[j]->mount_app(app_mps->value, what, 0) != -1) + break; } } what--; what[0] = '='; } else { - uwsgi_log("invalid mountpoint: %s\n", uwsgi.mounts[i]); + uwsgi_log("invalid mountpoint: %s\n", app_mps->value); exit(1); } + app_mps = app_mps->next; } // no app initialized and virtualhosting enabled @@ -3820,6 +3824,7 @@ void uwsgi_init_all_apps() { } void uwsgi_init_worker_mount_apps() { +/* int i,j; for (i = 0; i < uwsgi.mounts_cnt; i++) { char *what = strchr(uwsgi.mounts[i], '='); @@ -3843,6 +3848,7 @@ void uwsgi_init_worker_mount_apps() { exit(1); } } +*/ } @@ -4109,24 +4115,6 @@ void uwsgi_opt_load_plugin(char *opt, char *value, void *none) { } } -void uwsgi_opt_add_app(char *opt, char *value, void *foo) { - if (uwsgi.mounts_cnt < MAX_APPS) { - if (!strcmp(opt, "mount-regexp")) { - uwsgi.mounts[uwsgi.mounts_cnt] = uwsgi_concat2("regexp://", value); - } - else if (!strcmp(opt, "worker-mount")) { - uwsgi.mounts[uwsgi.mounts_cnt] = uwsgi_concat2("worker://", value); - } - else { - uwsgi.mounts[uwsgi.mounts_cnt] = value; - } - uwsgi.mounts_cnt++; - } - else { - uwsgi_log("you can specify at most %d --%s options\n", opt, MAX_APPS); - } -} - void uwsgi_opt_check_static(char *opt, char *value, void *foobar) { uwsgi_dyn_dict_new(&uwsgi.check_static, value, strlen(value), NULL, 0); diff --git a/plugins/gevent/gevent.c b/plugins/gevent/gevent.c index fa7e2d93..8128fa55 100644 --- a/plugins/gevent/gevent.c +++ b/plugins/gevent/gevent.c @@ -156,7 +156,7 @@ edge: wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi_sock ); // mark core as used - uwsgi.core[wsgi_req->async_id]->in_request = 1; + uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 1; gettimeofday(&wsgi_req->start_of_request, NULL); diff --git a/plugins/psgi/psgi_loader.c b/plugins/psgi/psgi_loader.c index 800078b2..70de36ed 100644 --- a/plugins/psgi/psgi_loader.c +++ b/plugins/psgi/psgi_loader.c @@ -432,6 +432,11 @@ int init_psgi_app(struct wsgi_request *wsgi_req, char *app, uint16_t app_len, Pe goto clear; } + if (uwsgi_apps_cnt >= uwsgi.max_apps) { + uwsgi_log("ERROR: you cannot load more than %d apps in a worker\n", uwsgi.max_apps); + goto clear; + } + int id = uwsgi_apps_cnt; struct uwsgi_app *wi = NULL; diff --git a/plugins/python/pyloader.c b/plugins/python/pyloader.c index df43689b..681551f2 100644 --- a/plugins/python/pyloader.c +++ b/plugins/python/pyloader.c @@ -77,7 +77,15 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre PyObject *app_list = NULL, *applications = NULL; + + if (uwsgi_apps_cnt >= uwsgi.max_apps) { + uwsgi_log("ERROR: you cannot load more than %d apps in a worker\n", uwsgi.max_apps); + return -1; + } + + int id = uwsgi_apps_cnt; + int multiapp = 0; int i; @@ -351,8 +359,8 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre // if we have multiple threads we need to initialize a PyThreadState for each one for(i=0;its[id]); - uwsgi.core[i]->ts[id] = PyThreadState_New( ((PyThreadState *)wi->interpreter)->interp); - if (!uwsgi.core[i]->ts[id]) { + uwsgi.workers[uwsgi.mywid].cores[i].ts[id] = PyThreadState_New( ((PyThreadState *)wi->interpreter)->interp); + if (!uwsgi.workers[uwsgi.mywid].cores[i].ts[id]) { uwsgi_log("unable to allocate new PyThreadState structure for app %s", wi->mountpoint); goto doh; } diff --git a/plugins/python/wsgi_handlers.c b/plugins/python/wsgi_handlers.c index d0cc63cc..b288cc28 100644 --- a/plugins/python/wsgi_handlers.c +++ b/plugins/python/wsgi_handlers.c @@ -584,7 +584,7 @@ void threaded_swap_ts(struct wsgi_request *wsgi_req, struct uwsgi_app *wi) { if (uwsgi.single_interpreter == 0 && wi->interpreter != up.main_thread) { UWSGI_GET_GIL - PyThreadState_Swap(uwsgi.core[wsgi_req->async_id]->ts[wsgi_req->app_id]); + PyThreadState_Swap(uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].ts[wsgi_req->app_id]); UWSGI_RELEASE_GIL } diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index bfb9b5a4..97f40897 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -399,6 +399,13 @@ VALUE uwsgi_rb_call_new(VALUE obj) { void uwsgi_rack_init_apps(void) { int error; + + if (uwsgi_apps_cnt >= uwsgi.max_apps) { + uwsgi_log("ERROR: you cannot load more than %d apps in a worker\n", uwsgi.max_apps); + return; + } + + ur.app_id = uwsgi_apps_cnt; struct uwsgi_string_list *usl = ur.rbrequire; diff --git a/uwsgi.h b/uwsgi.h index d2d57074..230aa2a4 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -53,7 +53,6 @@ extern "C" { #define UWSGI_OPT_CLUSTER (1 << 12) #define UWSGI_OPT_MIME (1 << 13) -#define MAX_APPS 64 #define MAX_GENERIC_PLUGINS 64 #define MAX_RPC 64 #define MAX_GATEWAYS 64 @@ -1268,8 +1267,6 @@ struct uwsgi_server { int loop_list; int clock_list; - //base for all the requests(even on async mode) - struct wsgi_request **wsgi_requests; struct wsgi_request *wsgi_req; char *remap_modifier; @@ -1563,6 +1560,7 @@ struct uwsgi_server { /* the list of workers */ struct uwsgi_worker *workers; + int max_apps; /* the list of mules */ struct uwsgi_string_list *mules_patches; @@ -1652,13 +1650,10 @@ struct uwsgi_server { time_t respawn_delta; - char *mounts[MAX_APPS]; - int mounts_cnt; + struct uwsgi_string_list *mounts; int cores; - struct uwsgi_core **core; - int threads; pthread_attr_t threads_attr; size_t threads_stacksize; @@ -1958,10 +1953,11 @@ struct uwsgi_core { pthread_t thread_id; #endif - //multiple ts per - core are needed only with multiple_interpreter + threads - void *ts[MAX_APPS]; + // one ts-perapp + void **ts; int in_request; + struct wsgi_request req; }; struct uwsgi_snapshot { @@ -2000,7 +1996,7 @@ struct uwsgi_worker { int destroy; int apps_cnt; - struct uwsgi_app apps[MAX_APPS]; + struct uwsgi_app *apps; uint64_t tx; @@ -2021,6 +2017,8 @@ struct uwsgi_worker { uint64_t static_offload_threads; + struct uwsgi_core *cores; + char name[0xff]; char snapshot_name[0xff]; }; @@ -2858,6 +2856,7 @@ struct uwsgi_gateway_socket *uwsgi_new_gateway_socket_from_fd(int, char *); void escape_shell_arg(char *, size_t, char *); void *uwsgi_malloc_shared(size_t); +void *uwsgi_calloc_shared(size_t); struct uwsgi_spooler *uwsgi_new_spooler(char *); @@ -2923,7 +2922,6 @@ void uwsgi_opt_set_gid(char *, char *, void *); void uwsgi_opt_set_env(char *, char *, void *); void uwsgi_opt_unset_env(char *, char *, void *); void uwsgi_opt_pidfile_signal(char *, char *, void *); -void uwsgi_opt_add_app(char *, char *, void *); void uwsgi_opt_check_static(char *, char *, void *); void uwsgi_opt_fileserve_mode(char *, char *, void *);