mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-28 17:55:39 +00:00
172 lines
3.4 KiB
C
172 lines
3.4 KiB
C
#include "uwsgi.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
|
|
struct wsgi_request *threaded_current_wsgi_req() {
|
|
return pthread_getspecific(uwsgi.tur_key);
|
|
}
|
|
struct wsgi_request *simple_current_wsgi_req() {
|
|
return uwsgi.wsgi_req;
|
|
}
|
|
|
|
|
|
void uwsgi_register_loop(char *name, void (*func) (void)) {
|
|
|
|
struct uwsgi_loop *old_loop = NULL, *loop = uwsgi.loops;
|
|
|
|
while (loop) {
|
|
// check if the loop engine is already registered
|
|
if (!strcmp(name, loop->name))
|
|
return;
|
|
old_loop = loop;
|
|
loop = loop->next;
|
|
}
|
|
|
|
loop = uwsgi_calloc(sizeof(struct uwsgi_loop));
|
|
loop->name = name;
|
|
loop->loop = func;
|
|
|
|
if (old_loop) {
|
|
old_loop->next = loop;
|
|
}
|
|
else {
|
|
uwsgi.loops = loop;
|
|
}
|
|
}
|
|
|
|
void *uwsgi_get_loop(char *name) {
|
|
|
|
struct uwsgi_loop *loop = uwsgi.loops;
|
|
|
|
while (loop) {
|
|
if (!strcmp(name, loop->name)) {
|
|
return loop->loop;
|
|
}
|
|
loop = loop->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
|
|
this is the default (simple) loop.
|
|
|
|
it will run simple_loop_run function for each spawned thread
|
|
|
|
simple_loop_run monitors sockets and signals descriptors
|
|
and manages them.
|
|
|
|
*/
|
|
|
|
void simple_loop() {
|
|
uwsgi_loop_cores_run(simple_loop_run);
|
|
}
|
|
|
|
void uwsgi_loop_cores_run(void *(*func) (void *)) {
|
|
int i;
|
|
#ifdef UWSGI_THREADING
|
|
for (i = 1; i < uwsgi.threads; i++) {
|
|
long j = i;
|
|
pthread_create(&uwsgi.workers[uwsgi.mywid].cores[i].thread_id, &uwsgi.threads_attr, func, (void *) j);
|
|
}
|
|
#endif
|
|
long y = 0;
|
|
func((void *) y);
|
|
}
|
|
|
|
void uwsgi_setup_thread_req(long core_id, struct wsgi_request *wsgi_req) {
|
|
int i;
|
|
sigset_t smask;
|
|
|
|
|
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &i);
|
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &i);
|
|
pthread_setspecific(uwsgi.tur_key, (void *) wsgi_req);
|
|
|
|
if (core_id > 0) {
|
|
// block all signals on new threads
|
|
sigfillset(&smask);
|
|
#ifdef UWSGI_DEBUG
|
|
sigdelset(&smask, SIGSEGV);
|
|
#endif
|
|
pthread_sigmask(SIG_BLOCK, &smask, NULL);
|
|
|
|
// run per-thread socket hook
|
|
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
|
while (uwsgi_sock) {
|
|
if (uwsgi_sock->proto_thread_fixup) {
|
|
uwsgi_sock->proto_thread_fixup(uwsgi_sock, core_id);
|
|
}
|
|
uwsgi_sock = uwsgi_sock->next;
|
|
}
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
if (uwsgi.p[i]->init_thread) {
|
|
uwsgi.p[i]->init_thread(core_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void simple_loop_run_int(int core_id) {
|
|
long y = core_id;
|
|
simple_loop_run((void *) y);
|
|
}
|
|
|
|
void *simple_loop_run(void *arg1) {
|
|
|
|
long core_id = (long) arg1;
|
|
|
|
struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core_id].req;
|
|
|
|
#ifdef UWSGI_THREADING
|
|
if (uwsgi.threads > 1) {
|
|
uwsgi_setup_thread_req(core_id, wsgi_req);
|
|
}
|
|
#endif
|
|
|
|
// initialize the main event queue to monitor sockets
|
|
int main_queue = event_queue_init();
|
|
|
|
uwsgi_add_sockets_to_queue(main_queue, core_id);
|
|
|
|
if (uwsgi.signal_socket > -1) {
|
|
event_queue_add_fd_read(main_queue, uwsgi.signal_socket);
|
|
event_queue_add_fd_read(main_queue, uwsgi.my_signal_socket);
|
|
}
|
|
|
|
|
|
// ok we are ready, let's start managing requests and signals
|
|
while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
|
|
|
wsgi_req_setup(wsgi_req, core_id, NULL);
|
|
|
|
if (wsgi_req_accept(main_queue, wsgi_req)) {
|
|
continue;
|
|
}
|
|
|
|
if (wsgi_req_recv(wsgi_req)) {
|
|
uwsgi_destroy_request(wsgi_req);
|
|
continue;
|
|
}
|
|
|
|
uwsgi_close_request(wsgi_req);
|
|
}
|
|
|
|
// end of the loop
|
|
if (uwsgi.workers[uwsgi.mywid].destroy && uwsgi.workers[0].pid > 0) {
|
|
#ifdef __APPLE__
|
|
kill(uwsgi.workers[0].pid, SIGTERM);
|
|
#else
|
|
if (uwsgi.propagate_touch) {
|
|
kill(uwsgi.workers[0].pid, SIGHUP);
|
|
}
|
|
else {
|
|
gracefully_kill(0);
|
|
}
|
|
#endif
|
|
}
|
|
return NULL;
|
|
}
|