1 #include "uwsgi.h"
2
3 extern struct uwsgi_server uwsgi;
4
threaded_current_wsgi_req()5 struct wsgi_request *threaded_current_wsgi_req() {
6 return pthread_getspecific(uwsgi.tur_key);
7 }
simple_current_wsgi_req()8 struct wsgi_request *simple_current_wsgi_req() {
9 return uwsgi.wsgi_req;
10 }
11
12
uwsgi_register_loop(char * name,void (* func)(void))13 void uwsgi_register_loop(char *name, void (*func) (void)) {
14
15 struct uwsgi_loop *old_loop = NULL, *loop = uwsgi.loops;
16
17 while (loop) {
18 // check if the loop engine is already registered
19 if (!strcmp(name, loop->name))
20 return;
21 old_loop = loop;
22 loop = loop->next;
23 }
24
25 loop = uwsgi_calloc(sizeof(struct uwsgi_loop));
26 loop->name = name;
27 loop->loop = func;
28
29 if (old_loop) {
30 old_loop->next = loop;
31 }
32 else {
33 uwsgi.loops = loop;
34 }
35 }
36
uwsgi_get_loop(char * name)37 void *uwsgi_get_loop(char *name) {
38
39 struct uwsgi_loop *loop = uwsgi.loops;
40
41 while (loop) {
42 if (!strcmp(name, loop->name)) {
43 return loop->loop;
44 }
45 loop = loop->next;
46 }
47 return NULL;
48 }
49
50 /*
51
52 this is the default (simple) loop.
53
54 it will run simple_loop_run function for each spawned thread
55
56 simple_loop_run monitors sockets and signals descriptors
57 and manages them.
58
59 */
60
simple_loop()61 void simple_loop() {
62 uwsgi_loop_cores_run(simple_loop_run);
63 if (uwsgi.workers[uwsgi.mywid].shutdown_sockets)
64 uwsgi_shutdown_all_sockets();
65 }
66
uwsgi_loop_cores_run(void * (* func)(void *))67 void uwsgi_loop_cores_run(void *(*func) (void *)) {
68 int i;
69 for (i = 1; i < uwsgi.threads; i++) {
70 long j = i;
71 pthread_create(&uwsgi.workers[uwsgi.mywid].cores[i].thread_id, &uwsgi.threads_attr, func, (void *) j);
72 }
73 long y = 0;
74 func((void *) y);
75 }
76
uwsgi_setup_thread_req(long core_id,struct wsgi_request * wsgi_req)77 void uwsgi_setup_thread_req(long core_id, struct wsgi_request *wsgi_req) {
78 int i;
79 sigset_t smask;
80
81
82 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &i);
83 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &i);
84 pthread_setspecific(uwsgi.tur_key, (void *) wsgi_req);
85
86 if (core_id > 0) {
87 // block all signals on new threads
88 sigfillset(&smask);
89 #ifdef UWSGI_DEBUG
90 sigdelset(&smask, SIGSEGV);
91 #endif
92 pthread_sigmask(SIG_BLOCK, &smask, NULL);
93
94 // run per-thread socket hook
95 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
96 while (uwsgi_sock) {
97 if (uwsgi_sock->proto_thread_fixup) {
98 uwsgi_sock->proto_thread_fixup(uwsgi_sock, core_id);
99 }
100 uwsgi_sock = uwsgi_sock->next;
101 }
102
103 for (i = 0; i < 256; i++) {
104 if (uwsgi.p[i]->init_thread) {
105 uwsgi.p[i]->init_thread(core_id);
106 }
107 }
108 }
109
110 }
111
simple_loop_run_int(int core_id)112 void simple_loop_run_int(int core_id) {
113 long y = core_id;
114 simple_loop_run((void *) y);
115 }
116
simple_loop_run(void * arg1)117 void *simple_loop_run(void *arg1) {
118
119 long core_id = (long) arg1;
120
121 struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core_id].req;
122
123 if (uwsgi.threads > 1) {
124 uwsgi_setup_thread_req(core_id, wsgi_req);
125 }
126 // initialize the main event queue to monitor sockets
127 int main_queue = event_queue_init();
128
129 uwsgi_add_sockets_to_queue(main_queue, core_id);
130
131 if (uwsgi.signal_socket > -1) {
132 event_queue_add_fd_read(main_queue, uwsgi.signal_socket);
133 event_queue_add_fd_read(main_queue, uwsgi.my_signal_socket);
134 }
135
136
137 // ok we are ready, let's start managing requests and signals
138 while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
139
140 wsgi_req_setup(wsgi_req, core_id, NULL);
141
142 if (wsgi_req_accept(main_queue, wsgi_req)) {
143 continue;
144 }
145
146 if (wsgi_req_recv(main_queue, wsgi_req)) {
147 uwsgi_destroy_request(wsgi_req);
148 continue;
149 }
150
151 uwsgi_close_request(wsgi_req);
152 }
153
154 // end of the loop
155 if (uwsgi.workers[uwsgi.mywid].destroy && uwsgi.workers[0].pid > 0) {
156 #ifdef __APPLE__
157 kill(uwsgi.workers[0].pid, SIGTERM);
158 #else
159 if (uwsgi.propagate_touch) {
160 kill(uwsgi.workers[0].pid, SIGHUP);
161 }
162 else {
163 gracefully_kill(0);
164 }
165 #endif
166 }
167 return NULL;
168 }
169