mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-22 05:25:48 +00:00
d4130dbc4b
preliminary api for language-independent body read another step completed body read language independent implementation ported gevent to the new read/write api ported websockets to the new read/write api removed channels subsystem removed channels subsystem ported lua to the new read/write api fixed post-buffering readline is still broken improved request body readline very difficult test for readline()/read() combo passed other improvements in postbuffering/read/readline ported --http-socket to the new api added X-Forwarded-SSL management removed old api more refactoring ported the RACK plugin to the new api ported psgi plugin to the new api defintely removed clustering simpified ifdel hell simpified ifdef hell removed useless configuration options
167 lines
3.4 KiB
C
167 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;
|
|
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);
|
|
}
|
|
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;
|
|
|
|
if (uwsgi.threads > 1) {
|
|
uwsgi_setup_thread_req(core_id, wsgi_req);
|
|
}
|
|
// 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(main_queue, 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;
|
|
}
|