mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
80
Commits
0.9.7-beta1
...
0.9.7.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9746759c68 | ||
|
|
170ee2b98a | ||
|
|
938fb777dd | ||
|
|
33e1aafcd1 | ||
|
|
597ee90041 | ||
|
|
e87e54ea28 | ||
|
|
5c64c1ac3f | ||
|
|
c611cbc2ca | ||
|
|
9d051f4171 | ||
|
|
6aee788678 | ||
|
|
425a45caa7 | ||
|
|
0571601e02 | ||
|
|
c1992c8c7a | ||
|
|
bd913870c7 | ||
|
|
7a479dd47f | ||
|
|
7ae77aa58d | ||
|
|
97a4260d44 | ||
|
|
b90d711764 | ||
|
|
22de5b523e | ||
|
|
5798b824c0 | ||
|
|
4cbf6cfc33 | ||
|
|
8b55460156 | ||
|
|
a61d48a451 | ||
|
|
b9f4d57d67 | ||
|
|
92cd36d14d | ||
|
|
f74e61b126 | ||
|
|
c8b4ba2b5b | ||
|
|
0a15ba1c5b | ||
|
|
7ee5948233 | ||
|
|
85c8bcf9d2 | ||
|
|
67394c6664 | ||
|
|
66ef7d8229 | ||
|
|
3773bc69f2 | ||
|
|
912416b119 | ||
|
|
7dfe125013 | ||
|
|
87db34ef0b | ||
|
|
d4f75ab53c | ||
|
|
dc97e8fce5 | ||
|
|
b3965d9d67 | ||
|
|
7ee90d1e12 | ||
|
|
9d8b373e4f | ||
|
|
a068a7eb5b | ||
|
|
aa004c1893 | ||
|
|
9a9c149370 | ||
|
|
9e6e226e4b | ||
|
|
06c2aed0e0 | ||
|
|
df4f610cfc | ||
|
|
64249abae1 | ||
|
|
94f4be58bd | ||
|
|
35987d3741 | ||
|
|
be73e00dde | ||
|
|
a5f272f337 | ||
|
|
406691aa69 | ||
|
|
6827b3bf15 | ||
|
|
2055a1472f | ||
|
|
f4f9018068 | ||
|
|
3e82b5cd33 | ||
|
|
07036bce20 | ||
|
|
a4a7a75f29 | ||
|
|
02d6006b2f | ||
|
|
e8e5f11c66 | ||
|
|
e53a6fa4c0 | ||
|
|
c478b0a0c8 | ||
|
|
5f207e6978 | ||
|
|
a2b74d0afd | ||
|
|
b867b11de3 | ||
|
|
806765d1d3 | ||
|
|
62d2b97e17 | ||
|
|
c04e339034 | ||
|
|
927b495646 | ||
|
|
57b5392590 | ||
|
|
463030108f | ||
|
|
46dd754264 | ||
|
|
12d9641b66 | ||
|
|
6cb1203d26 | ||
|
|
23d0ec333e | ||
|
|
da579fd308 | ||
|
|
14152bc999 | ||
|
|
6c32e5f2e2 | ||
|
|
62f74f2b60 |
@@ -9,3 +9,11 @@ b8f67c6cd0d62f864db9b2b265b4e260ad7d873c 0.9.6-rc2
|
||||
35918dd4b3771158b2b57410613ef029e08bbd60 0.9.6
|
||||
5f25d1f97f9dde3e391a668c1c610a52a5db8244 0.9.6.1
|
||||
ef31fc61ac48018c464f28ebfdf865b96bf83f18 0.9.6.2
|
||||
9e100c1f085034396cec586f0c76ad3f9800d1a5 0.9.7-beta1
|
||||
ff4111eb8f55b958ec91c70163e10f3372a9b94d 0.9.7-rc1
|
||||
eb8aff2926230bb114fb90f67203440a2c534bf1 0.9.7-rc2
|
||||
311eef929ec8fd0a5dc8c16531afb7bb42d36d01 0.9.7-rc3
|
||||
4b50c04e414f1d9ab8b0b5910aba83d09ac21abb 0.9.7
|
||||
d9b9b540f7dce8cb05d2e61ca8b4d75f2ea25f62 0.9.7.1
|
||||
d9b9b540f7dce8cb05d2e61ca8b4d75f2ea25f62 0.9.7.1
|
||||
0000000000000000000000000000000000000000 0.9.7.1
|
||||
|
||||
@@ -1,8 +1,82 @@
|
||||
*** march 2011 ***
|
||||
|
||||
* 0.9.7.1 [20110326]
|
||||
|
||||
- fixed python stackless support
|
||||
- added persistence for queue
|
||||
- forbid daemonizing in vassal mode
|
||||
- modifier1 30 is available again
|
||||
- allow python modules to be mapped/aliased via http
|
||||
- added --pidfile2 and --logfile-chown
|
||||
- added UWSGI_CACHE_GET dynamic variable
|
||||
- 304/If-Modified-Since support for --check-static
|
||||
- option --check-cache for integrated caching
|
||||
- option --map-socket to assign specific workers to socket
|
||||
- fixed unix fd passing on older OSX versions
|
||||
- fixed post-buffering without pep3333-input
|
||||
- fixed python threading without uwsgi cores
|
||||
- support for Linux network namespace
|
||||
- build with sys.abiflags if necessary
|
||||
|
||||
|
||||
* 0.9.7 [20110317]
|
||||
|
||||
- fixed psgi compilation on GNU systems
|
||||
- improved --pep3333-input
|
||||
- better error reporting on failed open/fopen
|
||||
- fixed uGreen
|
||||
- added greenlet support
|
||||
- various solaris fixes
|
||||
- new help system
|
||||
- updated async support
|
||||
- fixed uwsgi.cache_get in python
|
||||
|
||||
* 0.9.7-rc3 [20110312]
|
||||
|
||||
- added support for persistent cache (--cache-store <filename>)
|
||||
- less verbose file monitoring
|
||||
- fixed a race condition in emperor startup
|
||||
- fixed erlang empty list encoding
|
||||
- improved snmp support
|
||||
- fixed cache modifier 111 for 3 and 4
|
||||
- preliminary cpu-affinity support (Linux only)
|
||||
- fixed ldap support
|
||||
- auto-configure ldap compilation
|
||||
- added --allowed-modifiers (allow only a subset of modifiers)
|
||||
- fixed a bug with getopt_long
|
||||
|
||||
* 0.9.7-rc2 [20110309]
|
||||
|
||||
- added cron-like interface to signal framework
|
||||
- improved Linux namespaces support
|
||||
- fixed multithreading + --max-requests
|
||||
- added support for reference in configuration files
|
||||
|
||||
* 0.9.7-rc1 [20110307]
|
||||
|
||||
- export %v in emperor mode
|
||||
- fixed signal race condition in server reload
|
||||
- fixed http router post handling bug
|
||||
- added uwsgi.erlang_register_process in pyerl plugin
|
||||
- fixed unix socket inherit
|
||||
- fixed linux namespace support in recent kernel/gcc
|
||||
- ported threading to python 3.2
|
||||
- add build date to uWSGI startup info
|
||||
- do not allow clustering without defining a socket
|
||||
- kill all the gateways/daemons on startup errors
|
||||
- fixed vacuum after chdir()
|
||||
- fixed gateways reload
|
||||
- re-added support for OpenBSD and NetBSD
|
||||
- fixed post-buffering in python
|
||||
- use erlang binary for python string
|
||||
- fixed memory leak in pyerl plugin
|
||||
- removed broken log rotation (post-poned)
|
||||
- fixed no_argument options in ini and yaml parsing
|
||||
|
||||
* 0.9.7-beta1 [20110301]
|
||||
|
||||
- fully modular re-design
|
||||
- advanced build system with presets
|
||||
- threading support
|
||||
- emperor mode for massive auto-hosting
|
||||
- caching subsystem
|
||||
|
||||
@@ -2,198 +2,366 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
int async_get_timeout() {
|
||||
|
||||
struct wsgi_request* wsgi_req ;
|
||||
int i ;
|
||||
time_t curtime, tdelta = 0 ;
|
||||
int ret = 0 ;
|
||||
|
||||
// do not wait if there are cores running
|
||||
if (!uwsgi.async_running) return 0;
|
||||
|
||||
for(i=0;i<uwsgi.async_current_max;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
if (wsgi_req->async_timeout_expired) {
|
||||
// do not wait if there are timeout expired
|
||||
return 0;
|
||||
}
|
||||
if (wsgi_req->async_timeout > 0) {
|
||||
if (tdelta <= 0 || tdelta > wsgi_req->async_timeout) {
|
||||
tdelta = wsgi_req->async_timeout ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curtime = time(NULL);
|
||||
|
||||
ret = tdelta - curtime ;
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -1;
|
||||
struct wsgi_request *find_wsgi_req_by_fd(int fd) {
|
||||
return uwsgi.async_waiting_fd_table[fd];
|
||||
}
|
||||
|
||||
void async_expire_timeouts() {
|
||||
void runqueue_remove(struct uwsgi_async_request *u_request) {
|
||||
|
||||
struct wsgi_request* wsgi_req ;
|
||||
int i ;
|
||||
time_t deadline = time(NULL);
|
||||
|
||||
|
||||
for(i=0;i<uwsgi.async_current_max;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i] ;
|
||||
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN && wsgi_req->async_timeout > 0) {
|
||||
if (wsgi_req->async_timeout <= deadline) {
|
||||
wsgi_req->async_timeout = 0 ;
|
||||
wsgi_req->async_timeout_expired = 1 ;
|
||||
if (wsgi_req->async_waiting_fd != -1) {
|
||||
event_queue_del_fd(uwsgi.async_queue, wsgi_req->async_waiting_fd);
|
||||
uwsgi.async_waiting_fd_table[wsgi_req->async_waiting_fd] = -1;
|
||||
wsgi_req->async_waiting_fd = -1;
|
||||
wsgi_req->async_waiting_fd_monitored = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
struct uwsgi_async_request *parent = u_request->prev;
|
||||
struct uwsgi_async_request *child = u_request->next;
|
||||
|
||||
if (parent) {
|
||||
parent->next = child;
|
||||
}
|
||||
if (child) {
|
||||
child->prev = parent;
|
||||
}
|
||||
|
||||
if (parent == NULL) {
|
||||
uwsgi.async_runqueue = child;
|
||||
}
|
||||
|
||||
if (u_request == uwsgi.async_runqueue_last) {
|
||||
uwsgi.async_runqueue_last = parent;
|
||||
}
|
||||
|
||||
free(u_request);
|
||||
|
||||
uwsgi.async_runqueue_cnt--;
|
||||
}
|
||||
|
||||
void runqueue_push(struct wsgi_request *wsgi_req) {
|
||||
|
||||
struct uwsgi_async_request *uar;
|
||||
|
||||
if (uwsgi.async_runqueue == NULL) {
|
||||
// empty runqueue, create a new one
|
||||
uwsgi.async_runqueue = uwsgi_malloc(sizeof(struct uwsgi_async_request));
|
||||
uwsgi.async_runqueue->next = NULL;
|
||||
uwsgi.async_runqueue->prev = NULL;
|
||||
uwsgi.async_runqueue->wsgi_req = wsgi_req;
|
||||
uwsgi.async_runqueue_last = uwsgi.async_runqueue;
|
||||
}
|
||||
else {
|
||||
uar = uwsgi_malloc(sizeof(struct uwsgi_async_request));
|
||||
uar->prev = uwsgi.async_runqueue_last;
|
||||
uar->next = NULL;
|
||||
uar->wsgi_req = wsgi_req;
|
||||
uwsgi.async_runqueue_last->next = uar;
|
||||
uwsgi.async_runqueue_last = uar;
|
||||
}
|
||||
|
||||
uwsgi.async_runqueue_cnt++;
|
||||
|
||||
}
|
||||
|
||||
struct wsgi_request *find_first_available_wsgi_req() {
|
||||
|
||||
struct wsgi_request* wsgi_req;
|
||||
int i ;
|
||||
struct wsgi_request *wsgi_req;
|
||||
|
||||
// optimization
|
||||
if (uwsgi.async_current_max > 1) {
|
||||
if (uwsgi.wsgi_requests[uwsgi.async_current_max-1]->async_status == UWSGI_OK) {
|
||||
//uwsgi_log("decreasing current max cores\n");
|
||||
uwsgi.async_current_max--;
|
||||
}
|
||||
if (uwsgi.async_queue_unused_ptr < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i] ;
|
||||
if (wsgi_req->async_status == UWSGI_OK) {
|
||||
// optimization
|
||||
if (i > uwsgi.async_current_max-1) uwsgi.async_current_max = i+1;
|
||||
wsgi_req->async_id = i;
|
||||
return wsgi_req ;
|
||||
wsgi_req = uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr];
|
||||
uwsgi.async_queue_unused_ptr--;
|
||||
return wsgi_req;
|
||||
}
|
||||
|
||||
void async_expire_timeouts() {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
time_t current_time = time(NULL);
|
||||
struct uwsgi_async_fd *uaf = NULL, *current_uaf;
|
||||
|
||||
struct uwsgi_rb_timer *urbt;
|
||||
|
||||
for(;;) {
|
||||
|
||||
urbt = uwsgi_min_rb_timer(uwsgi.rb_async_timeouts);
|
||||
|
||||
if (urbt == NULL) return;
|
||||
|
||||
if (urbt->key <= current_time) {
|
||||
wsgi_req = (struct wsgi_request *) urbt->data;
|
||||
// timeout expired
|
||||
wsgi_req->async_timed_out = 1;
|
||||
rb_erase(&wsgi_req->async_timeout->rbt, uwsgi.rb_async_timeouts);
|
||||
free(wsgi_req->async_timeout);
|
||||
wsgi_req->async_timeout = NULL;
|
||||
uaf = wsgi_req->waiting_fds;
|
||||
// remove fds from monitoring (no problem modifying the queue here, as the function is executed only when there are no fd ready)
|
||||
while(uaf) {
|
||||
event_queue_del_fd(uwsgi.async_queue, uaf->fd, uaf->event);
|
||||
uwsgi.async_waiting_fd_table[uaf->fd] = NULL;
|
||||
current_uaf = uaf;
|
||||
uaf = current_uaf->next;
|
||||
free(current_uaf);
|
||||
}
|
||||
wsgi_req->waiting_fds = NULL;
|
||||
// put th request in the runqueue
|
||||
runqueue_push(wsgi_req);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
struct wsgi_request *find_wsgi_req_by_fd(int fd) {
|
||||
void async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) {
|
||||
|
||||
struct wsgi_request* wsgi_req = NULL ;
|
||||
int core_id = uwsgi.async_waiting_fd_table[fd];
|
||||
struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds;
|
||||
|
||||
if (core_id == -1) return NULL;
|
||||
if (fd < 0) return ;
|
||||
|
||||
wsgi_req = uwsgi.wsgi_requests[core_id];
|
||||
//if (wsgi_req->async_waiting_fd_type == etype) return wsgi_req ;
|
||||
return wsgi_req;
|
||||
// find first slot
|
||||
while(uad) {
|
||||
last_uad = uad;
|
||||
uad = uad->next;
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
uad = uwsgi_malloc(sizeof(struct uwsgi_async_fd));
|
||||
uad->fd = fd;
|
||||
uad->event = event_queue_read();
|
||||
uad->prev = last_uad;
|
||||
uad->next = NULL;
|
||||
|
||||
}
|
||||
if (last_uad) {
|
||||
last_uad->next = uad;
|
||||
}
|
||||
else {
|
||||
wsgi_req->waiting_fds = uad;
|
||||
}
|
||||
|
||||
void async_set_timeout(struct wsgi_request *wsgi_req, time_t timeout) {
|
||||
|
||||
wsgi_req->async_timeout = time(NULL);
|
||||
wsgi_req->async_timeout += timeout;
|
||||
wsgi_req->async_timeout_expired = 0 ;
|
||||
if (timeout > 0) {
|
||||
async_add_timeout(wsgi_req, timeout);
|
||||
}
|
||||
uwsgi.async_waiting_fd_table[fd] = wsgi_req;
|
||||
event_queue_add_fd_read(uwsgi.async_queue, fd);
|
||||
|
||||
}
|
||||
|
||||
void async_write_all(char *data, size_t len) {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
int i;
|
||||
ssize_t rlen ;
|
||||
void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) {
|
||||
|
||||
for(i=0;i<uwsgi.async_current_max;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_status == UWSGI_PAUSED) {
|
||||
rlen = write(wsgi_req->poll.fd, data, len);
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("write()");
|
||||
if (timeout > 0 && wsgi_req->async_timeout == NULL) {
|
||||
wsgi_req->async_timeout = uwsgi_add_rb_timer(uwsgi.rb_async_timeouts, time(NULL)+timeout, wsgi_req);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) {
|
||||
|
||||
struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds;
|
||||
|
||||
if (fd < 0) return ;
|
||||
|
||||
// find first slot
|
||||
while(uad) {
|
||||
last_uad = uad;
|
||||
uad = uad->next;
|
||||
}
|
||||
|
||||
uad = uwsgi_malloc(sizeof(struct uwsgi_async_fd));
|
||||
uad->fd = fd;
|
||||
uad->event = event_queue_write();
|
||||
uad->prev = last_uad;
|
||||
uad->next = NULL;
|
||||
|
||||
if (last_uad) {
|
||||
last_uad->next = uad;
|
||||
}
|
||||
else {
|
||||
wsgi_req->waiting_fds = uad;
|
||||
}
|
||||
|
||||
if (timeout > 0) {
|
||||
async_add_timeout(wsgi_req, timeout);
|
||||
}
|
||||
|
||||
uwsgi.async_waiting_fd_table[fd] = wsgi_req;
|
||||
event_queue_add_fd_write(uwsgi.async_queue, fd);
|
||||
|
||||
}
|
||||
|
||||
void async_schedule_to_req(void) {
|
||||
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req);
|
||||
}
|
||||
|
||||
void *async_loop(void *arg1) {
|
||||
|
||||
struct uwsgi_async_fd *tmp_uaf;
|
||||
int interesting_fd, i;
|
||||
struct uwsgi_rb_timer *min_timeout;
|
||||
int timeout;
|
||||
|
||||
static struct uwsgi_async_request *current_request = NULL, *next_async_request = NULL;
|
||||
|
||||
void *events = event_queue_alloc(64);
|
||||
|
||||
uwsgi.async_runqueue = NULL;
|
||||
uwsgi.async_runqueue_cnt = 0;
|
||||
|
||||
// set a default request manager
|
||||
if (!uwsgi.schedule_to_req) uwsgi.schedule_to_req = async_schedule_to_req;
|
||||
|
||||
while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
|
||||
if (uwsgi.async_runqueue_cnt) {
|
||||
timeout = 0;
|
||||
}
|
||||
else {
|
||||
min_timeout = uwsgi_min_rb_timer(uwsgi.rb_async_timeouts);
|
||||
if (uwsgi.async_runqueue_cnt) {
|
||||
timeout = 0;
|
||||
}
|
||||
if (min_timeout) {
|
||||
timeout = min_timeout->key - time(NULL);
|
||||
if (timeout <= 0) {
|
||||
async_expire_timeouts();
|
||||
timeout = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wsgi_req->response_size += rlen ;
|
||||
timeout = -1;
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.async_nevents = event_queue_wait_multi(uwsgi.async_queue, timeout, events, 64);
|
||||
|
||||
// timeout ???
|
||||
if (uwsgi.async_nevents == 0) {
|
||||
async_expire_timeouts();
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi.async_nevents;i++) {
|
||||
// manage events
|
||||
interesting_fd = event_queue_interesting_fd(events, i);
|
||||
|
||||
// new request coming in
|
||||
if (interesting_fd == uwsgi.sockets[0].fd) {
|
||||
uwsgi.wsgi_req = find_first_available_wsgi_req();
|
||||
if (uwsgi.wsgi_req == NULL) {
|
||||
uwsgi_log("async queue is full !!!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
wsgi_req_setup(uwsgi.wsgi_req, uwsgi.wsgi_req->async_id );
|
||||
if (wsgi_req_simple_accept(uwsgi.wsgi_req, interesting_fd)) {
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(uwsgi.async_queue, interesting_fd);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(uwsgi.async_queue, interesting_fd);
|
||||
#endif
|
||||
|
||||
// on linux we do not need to reset the socket to blocking state
|
||||
#ifndef __linux__
|
||||
if (uwsgi.numproc > 1) {
|
||||
/* re-set blocking socket */
|
||||
if (fcntl(uwsgi.wsgi_req->poll.fd, F_SETFL, uwsgi.sockets[0].arg) < 0) {
|
||||
uwsgi_error("fcntl()");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (wsgi_req_simple_recv(uwsgi.wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// put request in the runqueue
|
||||
runqueue_push(uwsgi.wsgi_req);
|
||||
}
|
||||
else {
|
||||
// app event
|
||||
uwsgi.wsgi_req = find_wsgi_req_by_fd(interesting_fd);
|
||||
// unknown fd, remove it (for safety)
|
||||
if (uwsgi.wsgi_req == NULL) {
|
||||
close(interesting_fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
// remove all the fd monitors and timeout
|
||||
while(uwsgi.wsgi_req->waiting_fds) {
|
||||
#ifndef UWSGI_EVENT_USE_PORT
|
||||
event_queue_del_fd(uwsgi.async_queue, uwsgi.wsgi_req->waiting_fds->fd, uwsgi.wsgi_req->waiting_fds->event);
|
||||
#endif
|
||||
tmp_uaf = uwsgi.wsgi_req->waiting_fds;
|
||||
uwsgi.async_waiting_fd_table[tmp_uaf->fd] = NULL;
|
||||
uwsgi.wsgi_req->waiting_fds = tmp_uaf->next;
|
||||
free(tmp_uaf);
|
||||
}
|
||||
uwsgi.wsgi_req->waiting_fds = NULL;
|
||||
if (uwsgi.wsgi_req->async_timeout) {
|
||||
rb_erase(&uwsgi.wsgi_req->async_timeout->rbt, uwsgi.rb_async_timeouts);
|
||||
free(uwsgi.wsgi_req->async_timeout);
|
||||
uwsgi.wsgi_req->async_timeout = NULL;
|
||||
}
|
||||
|
||||
uwsgi.wsgi_req->async_ready_fd = 1;
|
||||
uwsgi.wsgi_req->async_last_ready_fd = interesting_fd;
|
||||
|
||||
// put the request in the runqueue again
|
||||
runqueue_push(uwsgi.wsgi_req);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void async_unpause_all() {
|
||||
|
||||
struct wsgi_request *wsgi_req ;
|
||||
int i;
|
||||
// event queue managed, give cpu to runqueue
|
||||
if (!current_request)
|
||||
current_request = uwsgi.async_runqueue;
|
||||
|
||||
if (uwsgi.async_runqueue_cnt) {
|
||||
|
||||
uwsgi.wsgi_req = current_request->wsgi_req;
|
||||
|
||||
uwsgi.schedule_to_req();
|
||||
uwsgi.wsgi_req->switches++;
|
||||
|
||||
next_async_request = current_request->next;
|
||||
// request ended ?
|
||||
if (uwsgi.wsgi_req->async_status == UWSGI_OK) {
|
||||
// remove all the monitored fds and timeout
|
||||
while(uwsgi.wsgi_req->waiting_fds) {
|
||||
#ifndef UWSGI_EVENT_USE_PORT
|
||||
event_queue_del_fd(uwsgi.async_queue, uwsgi.wsgi_req->waiting_fds->fd, uwsgi.wsgi_req->waiting_fds->event);
|
||||
#endif
|
||||
tmp_uaf = uwsgi.wsgi_req->waiting_fds;
|
||||
uwsgi.async_waiting_fd_table[tmp_uaf->fd] = NULL;
|
||||
uwsgi.wsgi_req->waiting_fds = tmp_uaf->next;
|
||||
free(tmp_uaf);
|
||||
}
|
||||
uwsgi.wsgi_req->waiting_fds = NULL;
|
||||
if (uwsgi.wsgi_req->async_timeout) {
|
||||
rb_erase(&uwsgi.wsgi_req->async_timeout->rbt, uwsgi.rb_async_timeouts);
|
||||
free(uwsgi.wsgi_req->async_timeout);
|
||||
uwsgi.wsgi_req->async_timeout = NULL;
|
||||
}
|
||||
|
||||
// remove from the list
|
||||
runqueue_remove(current_request);
|
||||
|
||||
uwsgi_close_request(uwsgi.wsgi_req);
|
||||
|
||||
// push wsgi_request in the unused stack
|
||||
uwsgi.async_queue_unused_ptr++;
|
||||
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = uwsgi.wsgi_req;
|
||||
|
||||
}
|
||||
else if (uwsgi.wsgi_req->waiting_fds || uwsgi.wsgi_req->async_timeout) {
|
||||
// remove this request from suspended list
|
||||
runqueue_remove(current_request);
|
||||
}
|
||||
|
||||
current_request = next_async_request;
|
||||
|
||||
for(i=0;i<uwsgi.async_current_max;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_status == UWSGI_PAUSED) {
|
||||
wsgi_req->async_status = UWSGI_AGAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct wsgi_request * async_loop() {
|
||||
|
||||
struct wsgi_request *wsgi_req ;
|
||||
int i ;
|
||||
int ret;
|
||||
|
||||
uwsgi.async_running = -1 ;
|
||||
|
||||
for(i=0;i<uwsgi.async_current_max;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
if (wsgi_req->sigwait) {
|
||||
uwsgi_log("waiting for signal\n");
|
||||
continue;
|
||||
}
|
||||
else if (wsgi_req->async_waiting_fd != -1 && !wsgi_req->async_waiting_fd_monitored) {
|
||||
// add fd to monitoring
|
||||
ret = -1;
|
||||
if (wsgi_req->async_waiting_fd_type == ASYNC_IN) {
|
||||
ret = event_queue_add_fd_read(uwsgi.async_queue, wsgi_req->async_waiting_fd);
|
||||
}
|
||||
else if (wsgi_req->async_waiting_fd_type == ASYNC_OUT) {
|
||||
ret = event_queue_add_fd_write(uwsgi.async_queue, wsgi_req->async_waiting_fd);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
// error adding fd to the async queue, better to close it...
|
||||
close(wsgi_req->async_waiting_fd);
|
||||
wsgi_req->async_status = UWSGI_OK ;
|
||||
return wsgi_req;
|
||||
}
|
||||
uwsgi.async_waiting_fd_table[wsgi_req->async_waiting_fd] = wsgi_req->async_id;
|
||||
wsgi_req->async_waiting_fd_monitored = 1;
|
||||
wsgi_req->async_status = UWSGI_AGAIN;
|
||||
}
|
||||
else if (wsgi_req->async_waiting_fd == -1 && wsgi_req->async_timeout <= 0) {
|
||||
uwsgi.async_running = 0 ;
|
||||
// st global wsgi_req
|
||||
uwsgi.wsgi_req = wsgi_req ;
|
||||
|
||||
uwsgi_log("!!! getting new part\n");
|
||||
wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req);;
|
||||
|
||||
wsgi_req->switches++;
|
||||
|
||||
if (wsgi_req->async_status < UWSGI_AGAIN) {
|
||||
return wsgi_req;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -13,16 +13,15 @@ sendfile = true
|
||||
minterpreters = true
|
||||
async = true
|
||||
evdis = false
|
||||
ldap = false
|
||||
ldap = auto
|
||||
pcre = auto
|
||||
stackless = false
|
||||
debug = false
|
||||
unbit = false
|
||||
xml_implementation = libxml2
|
||||
plugins =
|
||||
bin_name = uwsgi
|
||||
plugin_dir = .
|
||||
embedded_plugins = python, ping, nagios, rpc, fastrouter, http
|
||||
embedded_plugins = python, ping, nagios, rpc, fastrouter, http, ugreen
|
||||
|
||||
locking = auto
|
||||
event = auto
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[uwsgi]
|
||||
inherit = default
|
||||
plugin_dir = /usr/lib/uwsgi
|
||||
embedded_plugins = null
|
||||
@@ -330,6 +330,27 @@ int uwsgi_cache_del(char *key, uint16_t keylen) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uwsgi_cache_fix() {
|
||||
|
||||
uint64_t i;
|
||||
|
||||
for(i=0;i< uwsgi.cache_max_items;i++) {
|
||||
// valid record ?
|
||||
if (uwsgi.cache_items[i].keysize) {
|
||||
if (!uwsgi.cache_items[i].prev) {
|
||||
// put value in hash_table
|
||||
uwsgi.cache_hashtable[ uwsgi.cache_items[i].djbhash % 0xffff] = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// put this record in unused stack
|
||||
uwsgi.shared->cache_first_available_item = i;
|
||||
uwsgi.shared->cache_unused_stack_ptr++;
|
||||
uwsgi.cache_unused_stack[uwsgi.shared->cache_unused_stack_ptr] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int uwsgi_cache_set(char *key, uint16_t keylen, char *val, uint64_t vallen, uint64_t expires, uint16_t flags) {
|
||||
|
||||
uint64_t index = 0, last_index = 0 ;
|
||||
@@ -476,7 +497,7 @@ void cache_command(char *key, uint16_t keylen, char *val, uint16_t vallen, void
|
||||
if (!uwsgi_strncmp(key, keylen, "key", 3)) {
|
||||
val = uwsgi_cache_get(val, vallen, &tmp_vallen);
|
||||
if (val && tmp_vallen > 0) {
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, val, vallen);
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, val, tmp_vallen);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -528,6 +549,7 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_cache_del(wsgi_req->buffer, wsgi_req->uh.pktsize);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
// dict
|
||||
if (wsgi_req->uh.pktsize > 0) {
|
||||
|
||||
@@ -121,6 +121,9 @@ void emperor_add(char *name, time_t born) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
unsetenv("UWSGI_RELOADS");
|
||||
|
||||
uef = uwsgi_num2str(n_ui->pipe[1]);
|
||||
if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
|
||||
uwsgi_error("setenv()");
|
||||
@@ -219,10 +222,7 @@ void emperor_loop() {
|
||||
|
||||
if (!i_am_alone) {
|
||||
diedpid = waitpid(uwsgi.emperor_pid, &waitpid_status, WNOHANG);
|
||||
if (diedpid < 0) {
|
||||
uwsgi_error("waitpid()");
|
||||
}
|
||||
else if (diedpid > 0) {
|
||||
if (diedpid < 0 || diedpid > 0) {
|
||||
i_am_alone = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
#include <port.h>
|
||||
|
||||
#define UWSGI_EVENT_IN POLLIN
|
||||
#define UWSGI_EVENT_OUT POLLOUT
|
||||
|
||||
int event_queue_init() {
|
||||
|
||||
int port = port_create();
|
||||
@@ -18,7 +21,7 @@ int event_queue_init() {
|
||||
return port;
|
||||
}
|
||||
|
||||
int event_queue_del_fd(int eq, int fd) {
|
||||
int event_queue_del_fd(int eq, int fd, int event) {
|
||||
|
||||
if (port_dissociate(eq, PORT_SOURCE_FD, fd)) {
|
||||
uwsgi_error("port_disassociate");
|
||||
@@ -28,6 +31,17 @@ int event_queue_del_fd(int eq, int fd) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
int event_queue_fd_write_to_read(int eq, int fd) {
|
||||
|
||||
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLIN, NULL)) {
|
||||
uwsgi_error("port_associate");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int event_queue_interesting_fd_has_error(void *events, int id) {
|
||||
port_event_t *pe = (port_event_t *) events;
|
||||
@@ -76,12 +90,11 @@ int event_queue_interesting_fd(void *events, int id) {
|
||||
int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
||||
|
||||
int ret;
|
||||
uint_t nget;
|
||||
int i;
|
||||
uint_t nget = 1;
|
||||
timespec_t ts;
|
||||
port_event_t *pe;
|
||||
|
||||
if (timeout > 0) {
|
||||
if (timeout >= 0) {
|
||||
ts.tv_sec = timeout;
|
||||
ts.tv_nsec = 0;
|
||||
ret = port_getn(eq, events, nevents, &nget, &ts);
|
||||
@@ -99,13 +112,6 @@ int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
||||
}
|
||||
|
||||
pe = (port_event_t *) events;
|
||||
for(i=0;i<nget;i++) {
|
||||
if (pe[i].portev_source == PORT_SOURCE_FD) {
|
||||
if (port_associate(eq, pe[i].portev_source, pe[i].portev_object, pe[i].portev_events, NULL)) {
|
||||
uwsgi_error("port_associate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nget;
|
||||
}
|
||||
@@ -144,7 +150,6 @@ int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
||||
|
||||
if (pe.portev_source == PORT_SOURCE_FILE || pe.portev_source == PORT_SOURCE_TIMER) {
|
||||
*interesting_fd = (int) pe.portev_user;
|
||||
uwsgi_log("port event interesting_fd: %d\n", *interesting_fd);
|
||||
}
|
||||
else {
|
||||
*interesting_fd = (int) pe.portev_object;
|
||||
@@ -160,6 +165,9 @@ int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#define UWSGI_EVENT_IN EPOLLIN
|
||||
#define UWSGI_EVENT_OUT EPOLLOUT
|
||||
|
||||
int event_queue_init() {
|
||||
|
||||
int epfd;
|
||||
@@ -207,12 +215,13 @@ int event_queue_fd_write_to_read(int eq, int fd) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
int event_queue_del_fd(int eq, int fd) {
|
||||
int event_queue_del_fd(int eq, int fd, int event) {
|
||||
|
||||
struct epoll_event ee;
|
||||
|
||||
memset(&ee, 0, sizeof(struct epoll_event));
|
||||
ee.data.fd = fd;
|
||||
ee.events = event;
|
||||
|
||||
if (epoll_ctl(eq, EPOLL_CTL_DEL, fd, &ee)) {
|
||||
uwsgi_error("epoll_ctl()");
|
||||
@@ -298,6 +307,10 @@ int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_EVENT_USE_KQUEUE
|
||||
|
||||
#define UWSGI_EVENT_IN EVFILT_READ
|
||||
#define UWSGI_EVENT_OUT EVFILT_WRITE
|
||||
|
||||
int event_queue_init() {
|
||||
|
||||
int kfd = kqueue();
|
||||
@@ -329,11 +342,11 @@ int event_queue_fd_write_to_read(int eq, int fd) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
int event_queue_del_fd(int eq, int fd) {
|
||||
int event_queue_del_fd(int eq, int fd, int event) {
|
||||
|
||||
struct kevent kev;
|
||||
|
||||
EV_SET(&kev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||
EV_SET(&kev, fd, event, EV_DELETE, 0, 0, 0);
|
||||
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
||||
uwsgi_error("kevent()");
|
||||
return -1;
|
||||
@@ -516,7 +529,7 @@ int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
||||
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -831,3 +844,11 @@ struct uwsgi_timer *event_queue_ack_timer(int id) {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
inline int event_queue_read() {
|
||||
return UWSGI_EVENT_IN;
|
||||
}
|
||||
|
||||
inline int event_queue_write() {
|
||||
return UWSGI_EVENT_OUT;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,11 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
|
||||
|
||||
if (!uwsgi.master_process) {
|
||||
if (gw_pid > 0) {
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0,0,0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
loop();
|
||||
// never here !!! (i hope)
|
||||
exit(1);
|
||||
@@ -101,6 +106,11 @@ void gateway_respawn(int id) {
|
||||
|
||||
if (gw_pid == 0) {
|
||||
if (uwsgi.master_as_root) uwsgi_as_root();
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0,0,0)) {
|
||||
uwsgi_error("prctl()");
|
||||
}
|
||||
#endif
|
||||
ug->loop();
|
||||
// never here !!! (i hope)
|
||||
exit(1);
|
||||
|
||||
@@ -84,7 +84,6 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
|
||||
int lines = 1;
|
||||
|
||||
struct option *lopt, *aopt;
|
||||
char *section_asked = "uwsgi";
|
||||
char *colon;
|
||||
|
||||
@@ -126,26 +125,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
|
||||
ini_rstrip(key);
|
||||
val = ini_lstrip(val);
|
||||
ini_rstrip(val);
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(key, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char *)key);
|
||||
}
|
||||
else {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcmp("true", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
manage_opt(aopt->val, val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
add_exported_option((char *)key, val, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,14 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
#include <ldap.h>
|
||||
|
||||
#ifndef LDAP_OPT_SUCCESS
|
||||
#define LDAP_OPT_SUCCESS LDAP_SUCCESS
|
||||
#endif
|
||||
|
||||
#ifndef ldap_unbind_ext_s
|
||||
#define ldap_unbind_ext_s ldap_unbind_ext
|
||||
#endif
|
||||
|
||||
void ldap2uwsgi(char *ldapname, char *uwsginame) {
|
||||
char *ptr = uwsginame;
|
||||
|
||||
@@ -37,71 +45,162 @@ int calc_ldap_name(char *name) {
|
||||
return strlen(name) + counter;
|
||||
}
|
||||
|
||||
void uwsgi_ldap_schema_dump_ldif() {
|
||||
struct option *aopt, *lopt;
|
||||
struct uwsgi_ldap_entry {
|
||||
int num;
|
||||
char names[1024];
|
||||
int has_arg;
|
||||
};
|
||||
|
||||
|
||||
void uwsgi_name_to_ldap(char *src, char *dst) {
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
int i;
|
||||
int counter = 30000;
|
||||
char *ptr = dst;
|
||||
|
||||
memset(dst, 0, 1024);
|
||||
|
||||
strcat(dst, " 'uWSGI");
|
||||
|
||||
ptr+= 7;
|
||||
|
||||
for(i=0;i< (int)strlen(src);i++) {
|
||||
if (src[i] == '-') {
|
||||
i++;
|
||||
*ptr++= toupper( (int) src[i]);
|
||||
}
|
||||
else {
|
||||
*ptr++= src[i];
|
||||
}
|
||||
}
|
||||
|
||||
strcat(dst, "'");
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_ldap_entry *get_ldap_by_num(struct uwsgi_ldap_entry *root, int num, int count) {
|
||||
|
||||
int i;
|
||||
struct uwsgi_ldap_entry *ule;
|
||||
|
||||
for(i=0;i<count;i++) {
|
||||
ule = &root[i];
|
||||
if (ule->num == num) {
|
||||
return ule;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_ldap_entry *search_ldap_cache(struct uwsgi_ldap_entry *root, char *name, int count) {
|
||||
int i;
|
||||
struct uwsgi_ldap_entry *ule;
|
||||
|
||||
for(i=0;i<count;i++) {
|
||||
ule = &root[i];
|
||||
if (uwsgi_list_has_str(ule->names, name+1)) {
|
||||
return ule;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uwsgi_ldap_entry *get_ldap_names(int *count) {
|
||||
|
||||
struct option *aopt, *lopt;
|
||||
struct uwsgi_ldap_entry *ule, *entry;
|
||||
char ldap_name[1024];
|
||||
static int counter = 30000000;
|
||||
|
||||
*count = 0;
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
ule = uwsgi_malloc(sizeof(struct uwsgi_ldap_entry)*count_options(lopt));
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
|
||||
uwsgi_name_to_ldap((char *)aopt->name, ldap_name);
|
||||
|
||||
entry = search_ldap_cache(ule, ldap_name, *count);
|
||||
|
||||
if (entry) goto next;
|
||||
|
||||
if (aopt->flag) {
|
||||
entry = &ule[*count] ;
|
||||
entry->num = counter;
|
||||
strcpy(entry->names, ldap_name);
|
||||
counter++;
|
||||
*count = *count+1;
|
||||
}
|
||||
else {
|
||||
entry = get_ldap_by_num(ule, aopt->val, *count);
|
||||
if (entry) {
|
||||
strcat(entry->names, ldap_name);
|
||||
}
|
||||
else {
|
||||
entry = &ule[*count] ;
|
||||
entry->num = aopt->val;
|
||||
strcpy(entry->names, ldap_name);
|
||||
*count = *count+1;
|
||||
}
|
||||
}
|
||||
|
||||
entry->has_arg = aopt->has_arg;
|
||||
|
||||
next:
|
||||
lopt++;
|
||||
}
|
||||
|
||||
return ule;
|
||||
}
|
||||
|
||||
void uwsgi_ldap_schema_dump_ldif() {
|
||||
|
||||
int i;
|
||||
int items;
|
||||
|
||||
uwsgi_log("\n");
|
||||
uwsgi_log("dn: cn=uwsgi,cn=schema,cn=config\n");
|
||||
uwsgi_log("objectClass: olcSchemaConfig\n");
|
||||
uwsgi_log("cn: uwsgi\n");
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
||||
|
||||
if (aopt->flag) {
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", counter);
|
||||
counter++;
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
||||
|
||||
if (entry->has_arg) {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", aopt->val);
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (aopt->has_arg) {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
uwsgi_log("olcObjectClasses: ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
uwsgi_log("uWSGI");
|
||||
entry = &ule[i];
|
||||
|
||||
char *list2 = uwsgi_concat2(entry->names+1, "");
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
uwsgi_log(" $ ");
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("uWSGInull ))\n");
|
||||
@@ -112,67 +211,47 @@ void uwsgi_ldap_schema_dump_ldif() {
|
||||
}
|
||||
|
||||
void uwsgi_ldap_schema_dump() {
|
||||
struct option *aopt, *lopt;
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
int i;
|
||||
int counter = 30000;
|
||||
int items;
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);
|
||||
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
if (aopt->flag) {
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", counter);
|
||||
counter++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME 'uWSGI", aopt->val);
|
||||
}
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
entry = &ule[i];
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);
|
||||
|
||||
if (entry->has_arg) {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (aopt->has_arg) {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
uwsgi_log("objectclass ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");
|
||||
|
||||
while( (aopt = lopt) ) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
for(i=0;i<items;i++) {
|
||||
|
||||
entry = &ule[i];
|
||||
|
||||
char *list2 = uwsgi_concat2(entry->names+1, "");
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
uwsgi_log("%.*s $ ", strlen(p)-2, p+1);
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log("uWSGI");
|
||||
|
||||
for(i=0;i< (int)strlen(aopt->name);i++) {
|
||||
if (aopt->name[i] == '-') {
|
||||
i++;
|
||||
uwsgi_log("%c", toupper( (int) aopt->name[i]));
|
||||
}
|
||||
else {
|
||||
uwsgi_log("%c", aopt->name[i]);
|
||||
}
|
||||
}
|
||||
uwsgi_log(" $ ");
|
||||
lopt++;
|
||||
}
|
||||
|
||||
uwsgi_log("uWSGInull ))\n");
|
||||
|
||||
@@ -194,8 +273,6 @@ void uwsgi_ldap_config() {
|
||||
int desired_version = LDAP_VERSION3;
|
||||
int ret;
|
||||
|
||||
struct option *aopt, *lopt;
|
||||
|
||||
LDAPURLDesc *ldap_url;
|
||||
|
||||
if (uwsgi.ldap) {
|
||||
@@ -211,6 +288,8 @@ void uwsgi_ldap_config() {
|
||||
uwsgi_log("unable to parse LDAP url.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("[uWSGI] getting LDAP configuration from %s\n", url);
|
||||
|
||||
url_slash = strchr(url, '/');
|
||||
url_slash = strchr(url_slash + 1, '/');
|
||||
@@ -225,10 +304,17 @@ void uwsgi_ldap_config() {
|
||||
uwsgi_debug("LDAP BASE DN: %s\n", ldap_url->lud_dn);
|
||||
#endif
|
||||
|
||||
#if LDAP_API_VERSION >= 3000
|
||||
if ( (ret = ldap_initialize( &ldp, url)) != LDAP_SUCCESS) {
|
||||
uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
if ( (ldp = ldap_init( ldap_url->lud_host, ldap_url->lud_port)) == NULL) {
|
||||
uwsgi_error("ldap_init()");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if ( (ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) {
|
||||
@@ -255,9 +341,11 @@ void uwsgi_ldap_config() {
|
||||
|
||||
entry = ldap_first_entry(ldp, results);
|
||||
|
||||
int found = 0;
|
||||
for( attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
|
||||
if (!strncmp(attr,"uWSGI",5)) {
|
||||
|
||||
found = 1;
|
||||
uwsgi_attr = malloc( calc_ldap_name(attr) + 1 );
|
||||
if (!uwsgi_attr) {
|
||||
uwsgi_error("malloc()");
|
||||
@@ -271,7 +359,7 @@ void uwsgi_ldap_config() {
|
||||
#endif
|
||||
bervalues = ldap_get_values_len(ldp, entry, attr);
|
||||
if (bervalues) {
|
||||
// do not free uwsgi_val;
|
||||
// do not free uwsgi_attr/uwsgi_val;
|
||||
char *uwsgi_val = malloc( bervalues[0]->bv_len + 1 );
|
||||
if (!uwsgi_val) {
|
||||
uwsgi_error("malloc()");
|
||||
@@ -281,29 +369,21 @@ void uwsgi_ldap_config() {
|
||||
memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len);
|
||||
uwsgi_val[bervalues[0]->bv_len] = 0;
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(uwsgi_attr, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char*) uwsgi_attr);
|
||||
}
|
||||
else {
|
||||
manage_opt(aopt->val, uwsgi_val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
add_exported_option((char*) uwsgi_attr, uwsgi_val, 0);
|
||||
free(bervalues);
|
||||
}
|
||||
else {
|
||||
free(uwsgi_attr);
|
||||
}
|
||||
|
||||
free(bervalues);
|
||||
free(uwsgi_attr);
|
||||
}
|
||||
free(attr);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
uwsgi_log("no uWSGI LDAP entry found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
free(ber);
|
||||
free(results);
|
||||
|
||||
|
||||
@@ -134,14 +134,36 @@ void uwsgi_rwunlock(void *lock) { uwsgi_unlock(lock); }
|
||||
#define UWSGI_LOCK_SIZE 8
|
||||
#define UWSGI_RWLOCK_SIZE 8
|
||||
|
||||
void uwsgi_lock_init(void *lock) {}
|
||||
static int lock_counter = 0;
|
||||
|
||||
void uwsgi_lock_init(void *lock) {
|
||||
|
||||
char filename[17];
|
||||
|
||||
if (snprintf(filename, 17, ".uwsgiflock%d", lock_counter) < 0) {
|
||||
uwsgi_log("unable to create lock %d\n", lock_counter);
|
||||
}
|
||||
|
||||
int fd = open(filename, O_CREAT|O_RDWR|O_TRUNC);
|
||||
if (fd < 0) {
|
||||
uwsgi_error_open(filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(lock, &fd, sizeof(int));
|
||||
}
|
||||
|
||||
void uwsgi_lock(void *lock) {
|
||||
//if (flock((int) *lock, LOCK_EX)) { uwsgi_error("flock()"); }
|
||||
|
||||
int fd;
|
||||
memcpy(&fd, lock, sizeof(int));
|
||||
if (flock(fd, LOCK_EX)) { uwsgi_error("flock()"); }
|
||||
}
|
||||
|
||||
void uwsgi_unlock(void *lock) {
|
||||
//if (flock((int) *lock, LOCK_UN)) { uwsgi_error("flock()"); }
|
||||
int fd;
|
||||
memcpy(&fd, lock, sizeof(int));
|
||||
if (flock(fd, LOCK_UN)) { uwsgi_error("flock()"); }
|
||||
}
|
||||
|
||||
void uwsgi_rwlock_init(void *lock) { uwsgi_lock_init(lock) ;}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define _NO_UWSGI_RB
|
||||
#include "uwsgi.h"
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
||||
|
||||
@@ -87,106 +87,3 @@ void *simple_loop(void *arg1) {
|
||||
//never here
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
void complex_loop() {
|
||||
int current_async_timeout = 0;
|
||||
int i, j;
|
||||
int interesting_fd;
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
|
||||
while (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
|
||||
current_async_timeout = async_get_timeout();
|
||||
|
||||
uwsgi.async_nevents = event_queue_wait_multi(uwsgi.async_queue, current_async_timeout, uwsgi.async_events, 64);
|
||||
async_expire_timeouts();
|
||||
|
||||
if (uwsgi.async_nevents < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(i=0; i<uwsgi.async_nevents;i++) {
|
||||
|
||||
interesting_fd = event_queue_interesting_fd(uwsgi.async_events, i);
|
||||
|
||||
if ( interesting_fd == uwsgi.sockets[0].fd) {
|
||||
|
||||
uwsgi.wsgi_req = find_first_available_wsgi_req();
|
||||
if (uwsgi.wsgi_req == NULL) {
|
||||
// async system is full !!!
|
||||
goto cycle;
|
||||
}
|
||||
|
||||
wsgi_req_setup(uwsgi.wsgi_req, uwsgi.wsgi_req->async_id );
|
||||
|
||||
if (wsgi_req_simple_accept(uwsgi.wsgi_req, interesting_fd)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// on linux we do not need to reset the socket to blocking state
|
||||
#ifndef __linux__
|
||||
if (uwsgi.numproc > 1) {
|
||||
/* re-set blocking socket */
|
||||
if (fcntl(uwsgi.wsgi_req->poll.fd, F_SETFL, uwsgi.sockets[0].arg) < 0) {
|
||||
uwsgi_error("fcntl()");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wsgi_req_recv(uwsgi.wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uwsgi.wsgi_req->async_status == UWSGI_OK) {
|
||||
goto reqclear;
|
||||
}
|
||||
|
||||
}
|
||||
else if ( interesting_fd == uwsgi.sockets_poll[uwsgi.sockets_cnt].fd) {
|
||||
// wake up cores waiting for signal
|
||||
char byte;
|
||||
if (read(uwsgi.sockets_poll[uwsgi.sockets_cnt].fd, &byte, 1) == 1) {
|
||||
}
|
||||
else {
|
||||
uwsgi_error("read()");
|
||||
}
|
||||
for(j=0;j<uwsgi.async_current_max;j++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[j] ;
|
||||
if (wsgi_req->sigwait) {
|
||||
wsgi_req->signal_received = byte;
|
||||
wsgi_req->sigwait = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi.wsgi_req = find_wsgi_req_by_fd(interesting_fd);
|
||||
if (uwsgi.wsgi_req) {
|
||||
uwsgi.wsgi_req->async_status = UWSGI_AGAIN;
|
||||
uwsgi.wsgi_req->async_waiting_fd = -1;
|
||||
uwsgi.wsgi_req->async_waiting_fd_monitored = 0;
|
||||
uwsgi.wsgi_req->async_timeout = 0;
|
||||
}
|
||||
|
||||
event_queue_del_fd(uwsgi.async_queue, interesting_fd);
|
||||
}
|
||||
}
|
||||
|
||||
cycle:
|
||||
|
||||
uwsgi.wsgi_req = async_loop();
|
||||
|
||||
if (uwsgi.wsgi_req == NULL)
|
||||
continue;
|
||||
uwsgi.wsgi_req->async_status = UWSGI_OK;
|
||||
|
||||
reqclear:
|
||||
uwsgi_close_request(uwsgi.wsgi_req);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -125,7 +125,7 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
char log_buf[4096];
|
||||
|
||||
uint64_t current_time = time(NULL);
|
||||
time_t current_time = time(NULL);
|
||||
|
||||
struct timeval last_respawn;
|
||||
|
||||
@@ -146,8 +146,6 @@ void master_loop(char **argv, char **environ) {
|
||||
uint8_t uwsgi_signal;
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
struct pollfd uwsgi_poll[2];
|
||||
int uwsgi_poll_size = 0;
|
||||
struct sockaddr_in udp_client;
|
||||
socklen_t udp_len;
|
||||
char udp_client_addr[16];
|
||||
@@ -165,6 +163,10 @@ void master_loop(char **argv, char **environ) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
int snmp_fd = -1;
|
||||
#endif
|
||||
|
||||
int i=0,j;
|
||||
int rlen;
|
||||
|
||||
@@ -172,21 +174,19 @@ void master_loop(char **argv, char **environ) {
|
||||
|
||||
struct uwsgi_rb_timer *min_timeout;
|
||||
struct rb_root *rb_timers = uwsgi_init_rb_timer();
|
||||
struct tm *uwsgi_cron_delta;
|
||||
|
||||
// release the GIL
|
||||
//UWSGI_RELEASE_GIL
|
||||
|
||||
/* route signals to workers... */
|
||||
signal(SIGHUP, (void *) &grace_them_all);
|
||||
signal(SIGTERM, (void *) &reap_them_all);
|
||||
signal(SIGINT, (void *) &kill_them_all);
|
||||
signal(SIGQUIT, (void *) &kill_them_all);
|
||||
/* used only to avoid human-errors */
|
||||
uwsgi_unix_signal(SIGHUP, grace_them_all);
|
||||
uwsgi_unix_signal(SIGTERM, reap_them_all);
|
||||
uwsgi_unix_signal(SIGINT, kill_them_all);
|
||||
uwsgi_unix_signal(SIGQUIT, kill_them_all);
|
||||
uwsgi_unix_signal(SIGUSR1, stats);
|
||||
|
||||
signal(SIGUSR1, (void *) &stats);
|
||||
|
||||
uwsgi.master_queue = event_queue_init();
|
||||
|
||||
/* route signals to workers... */
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("adding %d to signal poll\n", uwsgi.shared->worker_signal_pipe[0]);
|
||||
#endif
|
||||
@@ -208,21 +208,16 @@ void master_loop(char **argv, char **environ) {
|
||||
#ifdef UWSGI_UDP
|
||||
if (uwsgi.udp_socket) {
|
||||
udp_fd = bind_to_udp(uwsgi.udp_socket, 0, 0);
|
||||
uwsgi_poll[uwsgi_poll_size].fd = udp_fd;
|
||||
if (uwsgi_poll[uwsgi_poll_size].fd < 0) {
|
||||
if (udp_fd < 0) {
|
||||
uwsgi_log( "unable to bind to udp socket. SNMP and cluster management services will be disabled.\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "UDP server enabled.\n");
|
||||
uwsgi_poll[uwsgi_poll_size].events = POLLIN;
|
||||
uwsgi_poll_size++;
|
||||
event_queue_add_fd_read(uwsgi.master_queue, udp_fd);
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_MULTICAST
|
||||
if (uwsgi.cluster) {
|
||||
uwsgi_poll[uwsgi_poll_size].fd = uwsgi.cluster_fd;
|
||||
uwsgi_poll[uwsgi_poll_size].events = POLLIN;
|
||||
uwsgi_poll_size++;
|
||||
|
||||
event_queue_add_fd_read(uwsgi.master_queue, uwsgi.cluster_fd);
|
||||
|
||||
@@ -245,6 +240,10 @@ void master_loop(char **argv, char **environ) {
|
||||
uh->modifier1 = 99;
|
||||
uh->pktsize = cluster_opt_size - 4;
|
||||
uh->modifier2 = 1;
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uh->pktsize = uwsgi_swap16(uh->pktsize);
|
||||
#endif
|
||||
|
||||
cptrbuf = cluster_opt_buf+4;
|
||||
|
||||
@@ -286,12 +285,28 @@ void master_loop(char **argv, char **environ) {
|
||||
memcpy(uwsgi.shared->snmp_community, uwsgi.snmp_community, strlen(uwsgi.snmp_community) + 1);
|
||||
}
|
||||
}
|
||||
uwsgi_log( "filling SNMP table...");
|
||||
|
||||
uwsgi.shared->snmp_gvalue[0].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[0].val = &uwsgi.workers[0].requests;
|
||||
|
||||
uwsgi_log( "done\n");
|
||||
for(i=0;i<uwsgi.numproc;i++) {
|
||||
uwsgi.shared->snmp_gvalue[30+i].type = SNMP_COUNTER64;
|
||||
uwsgi.shared->snmp_gvalue[30+i].val = &uwsgi.workers[i+1].requests;
|
||||
}
|
||||
|
||||
if (uwsgi.snmp_addr) {
|
||||
snmp_fd = bind_to_udp(uwsgi.snmp_addr, 0, 0);
|
||||
if (snmp_fd < 0) {
|
||||
uwsgi_log( "unable to bind to udp socket. SNMP service will be disabled.\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "SNMP server enabled on %s\n", uwsgi.snmp_addr);
|
||||
event_queue_add_fd_read(uwsgi.master_queue, snmp_fd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "SNMP agent enabled.\n");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -315,6 +330,19 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_subscribe(uwsgi.subscriptions[i]);
|
||||
}
|
||||
|
||||
// sync the cache store if needed
|
||||
if (uwsgi.cache_store && uwsgi.cache_filesize) {
|
||||
if (msync(uwsgi.cache_items, uwsgi.cache_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.queue_store && uwsgi.queue_filesize) {
|
||||
if (msync(uwsgi.queue, uwsgi.queue_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
//uwsgi_log("ready_to_reload %d %d\n", ready_to_reload, uwsgi.numproc);
|
||||
|
||||
@@ -361,6 +389,11 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
|
||||
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
|
||||
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
|
||||
}
|
||||
|
||||
uwsgi_log( "binary reloading uWSGI...\n");
|
||||
if (chdir(uwsgi.cwd)) {
|
||||
uwsgi_error("chdir()");
|
||||
@@ -407,12 +440,6 @@ void master_loop(char **argv, char **environ) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef UWSGI_PROXY
|
||||
if (uwsgi.proxy_socket_name && uwsgi.shared->proxy_pid > 0) {
|
||||
master_has_children = 1;
|
||||
}
|
||||
// TODO if gateways > 0 master_has_children == 1
|
||||
#endif
|
||||
|
||||
if (!master_has_children) {
|
||||
diedpid = 0;
|
||||
@@ -423,7 +450,7 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("waitpid()");
|
||||
/* here is better to reload all the uWSGI stack */
|
||||
uwsgi_log( "something horrible happened...\n");
|
||||
reap_them_all();
|
||||
reap_them_all(0);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -497,6 +524,75 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check uwsgi-cron table
|
||||
if (ushared->cron_cnt) {
|
||||
current_time = time(NULL);
|
||||
uwsgi_cron_delta = localtime( ¤t_time );
|
||||
|
||||
if (uwsgi_cron_delta) {
|
||||
|
||||
// fix month
|
||||
uwsgi_cron_delta->tm_mon++;
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
for(i=0;i<ushared->cron_cnt;i++) {
|
||||
|
||||
struct uwsgi_cron *ucron = &ushared->cron[i];
|
||||
int uc_minute, uc_hour, uc_day, uc_month, uc_week;
|
||||
|
||||
uc_minute = ucron->minute;
|
||||
uc_hour = ucron->hour;
|
||||
uc_day = ucron->day;
|
||||
uc_month = ucron->month;
|
||||
uc_week = ucron->week;
|
||||
|
||||
if (ucron->minute == -1) uc_minute = uwsgi_cron_delta->tm_min;
|
||||
if (ucron->hour == -1) uc_hour = uwsgi_cron_delta->tm_hour;
|
||||
if (ucron->month == -1) uc_month = uwsgi_cron_delta->tm_mon;
|
||||
|
||||
// mday and wday are ORed
|
||||
if (ucron->day == -1 && ucron->week == -1) {
|
||||
if (ucron->day == -1) uc_day = uwsgi_cron_delta->tm_mday;
|
||||
if (ucron->week == -1) uc_week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->day == -1) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
else if (ucron->week == -1) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else {
|
||||
if (ucron->day == uwsgi_cron_delta->tm_mday) {
|
||||
ucron->week = uwsgi_cron_delta->tm_wday;
|
||||
}
|
||||
else if (ucron->week == uwsgi_cron_delta->tm_wday) {
|
||||
ucron->day = uwsgi_cron_delta->tm_mday;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi_cron_delta->tm_min == uc_minute &&
|
||||
uwsgi_cron_delta->tm_hour == uc_hour &&
|
||||
uwsgi_cron_delta->tm_mon == uc_month &&
|
||||
uwsgi_cron_delta->tm_mday == uc_day &&
|
||||
uwsgi_cron_delta->tm_wday == uc_week) {
|
||||
|
||||
|
||||
// date match, signal it ?
|
||||
if (current_time - ucron->last_job > 60) {
|
||||
uwsgi_route_signal(ucron->sig);
|
||||
ucron->last_job = current_time;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
}
|
||||
else {
|
||||
uwsgi_error("localtime()");
|
||||
}
|
||||
}
|
||||
|
||||
if (rlen > 0) {
|
||||
|
||||
if (uwsgi.log_master) {
|
||||
@@ -521,21 +617,35 @@ void master_loop(char **argv, char **environ) {
|
||||
if (byte == 0) {
|
||||
close(uwsgi.emperor_fd);
|
||||
uwsgi.has_emperor = 0;
|
||||
kill_them_all();
|
||||
kill_them_all(0);
|
||||
}
|
||||
// reload me
|
||||
else if (byte == 1) {
|
||||
grace_them_all();
|
||||
grace_them_all(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("lost connection with my emperor !!!\n");
|
||||
close(uwsgi.emperor_fd);
|
||||
uwsgi.has_emperor = 0;
|
||||
kill_them_all();
|
||||
kill_them_all(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef UWSGI_SNMP
|
||||
if (uwsgi.snmp_addr && interesting_fd == snmp_fd) {
|
||||
udp_len = sizeof(udp_client);
|
||||
rlen = recvfrom(snmp_fd, uwsgi.wsgi_req->buffer, uwsgi.buffer_size, 0, (struct sockaddr *) &udp_client, &udp_len);
|
||||
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("recvfrom()");
|
||||
}
|
||||
else if (rlen > 0) {
|
||||
manage_snmp(snmp_fd, (uint8_t *) uwsgi.wsgi_req->buffer, rlen, &udp_client);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
if (uwsgi.udp_socket && interesting_fd == udp_fd) {
|
||||
@@ -593,12 +703,19 @@ void master_loop(char **argv, char **environ) {
|
||||
switch(uwsgi.wsgi_requests[0]->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);
|
||||
#endif
|
||||
uwsgi_hooked_parse(uwsgi.wsgi_requests[0]->buffer, uwsgi.wsgi_requests[0]->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);
|
||||
#endif
|
||||
uwsgi_log_verbose("%.*s\n", uwsgi.wsgi_requests[0]->uh.pktsize, uwsgi.wsgi_requests[0]->buffer);
|
||||
break;
|
||||
case 98:
|
||||
@@ -614,6 +731,9 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
break;
|
||||
case 73:
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uwsgi.wsgi_requests[0]->uh.pktsize = uwsgi_swap16(uwsgi.wsgi_requests[0]->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);
|
||||
break;
|
||||
}
|
||||
@@ -629,7 +749,6 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_lock(uwsgi.fmon_table_lock);
|
||||
for(i=0;i<ushared->files_monitored_cnt;i++) {
|
||||
if (ushared->files_monitored[i].registered) {
|
||||
uwsgi_log("fmon check %d == %d\n", interesting_fd, ushared->files_monitored[i].fd) ;
|
||||
if (interesting_fd == ushared->files_monitored[i].fd) {
|
||||
struct uwsgi_fmon *uf = event_queue_ack_file_monitor(uwsgi.master_queue, interesting_fd);
|
||||
// now call the file_monitor handler
|
||||
@@ -679,6 +798,7 @@ void master_loop(char **argv, char **environ) {
|
||||
// checking logsize
|
||||
if (uwsgi.logfile) {
|
||||
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
|
||||
/*
|
||||
if (uwsgi.shared->logsize > 8192) {
|
||||
//uwsgi_log("logsize: %d\n", uwsgi.shared->logsize);
|
||||
char *new_logfile = uwsgi_malloc(strlen(uwsgi.logfile) + 14 + 1);
|
||||
@@ -688,6 +808,7 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
free(new_logfile);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -698,16 +819,6 @@ void master_loop(char **argv, char **environ) {
|
||||
// recalculate requests counter on race conditions risky configurations
|
||||
// a bit of inaccuracy is better than locking;)
|
||||
|
||||
if (uwsgi.cores > 1) {
|
||||
for(i=1;i<uwsgi.numproc+1;i++) {
|
||||
tmp_counter = 0;
|
||||
for(j=0;j<uwsgi.cores;j++) {
|
||||
tmp_counter += uwsgi.core[j]->requests;
|
||||
}
|
||||
uwsgi.workers[i].requests = tmp_counter;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.numproc > 1) {
|
||||
tmp_counter = 0;
|
||||
for(i=1;i<uwsgi.numproc+1;i++) {
|
||||
@@ -716,12 +827,12 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi.workers[0].requests = tmp_counter;
|
||||
}
|
||||
|
||||
// remove expired cache items
|
||||
// remove expired cache items TODO use rb_tree timeouts
|
||||
if (uwsgi.cache_max_items > 0) {
|
||||
for(i=0;i< (int)uwsgi.cache_max_items;i++) {
|
||||
uwsgi_wlock(uwsgi.cache_lock);
|
||||
if (uwsgi.cache_items[i].expires) {
|
||||
if (uwsgi.cache_items[i].expires < current_time) {
|
||||
if (uwsgi.cache_items[i].expires < (uint64_t) current_time) {
|
||||
uwsgi_cache_del(uwsgi.cache_items[i].key, uwsgi.cache_items[i].keysize);
|
||||
}
|
||||
}
|
||||
@@ -839,6 +950,18 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.cache_store && uwsgi.cache_filesize && uwsgi.cache_store_sync && ((master_cycles % uwsgi.cache_store_sync) == 0)) {
|
||||
if (msync(uwsgi.cache_items, uwsgi.cache_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.queue_store && uwsgi.queue_filesize && uwsgi.queue_store_sync && ((master_cycles % uwsgi.queue_store_sync) == 0)) {
|
||||
if (msync(uwsgi.queue, uwsgi.queue_filesize, MS_ASYNC)) {
|
||||
uwsgi_error("msync()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -929,7 +1052,9 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log( "DAMN ! process %d died :( trying respawn ...\n", diedpid);
|
||||
if (uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
uwsgi_log( "DAMN ! worker %d (pid: %d) died :( trying respawn ...\n", uwsgi.mywid, (int)diedpid);
|
||||
}
|
||||
gettimeofday(&last_respawn, NULL);
|
||||
if (last_respawn.tv_sec == uwsgi.respawn_delta) {
|
||||
uwsgi_log( "worker respawning too fast !!! i have to sleep a bit...\n");
|
||||
@@ -964,28 +1089,9 @@ void master_loop(char **argv, char **environ) {
|
||||
uwsgi_error("fork()");
|
||||
}
|
||||
else {
|
||||
uwsgi_log( "Respawned uWSGI worker (new pid: %d)\n", pid);
|
||||
//close(uwsgi.workers[uwsgi.mywid].pipe[1]);
|
||||
//event_queue_add_fd_read(uwsgi.master_queue, uwsgi.workers[uwsgi.mywid].pipe[0]);
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.mywid <= 0 && diedpid != uwsgi.shared->spooler_pid) {
|
||||
#else
|
||||
if (uwsgi.mywid <= 0) {
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_PROXY
|
||||
// TODO if no gateway span the error !!!
|
||||
if (diedpid != uwsgi.shared->proxy_pid) {
|
||||
#endif
|
||||
uwsgi_log( "warning the died pid was not in the workers list. Probably you hit a BUG of uWSGI\n");
|
||||
#ifdef UWSGI_PROXY
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uwsgi_log( "Respawned uWSGI worker %d (new pid: %d)\n", uwsgi.mywid, (int) pid);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
[uwsgi]
|
||||
|
||||
; socket 0
|
||||
socket = :3033
|
||||
; socket 1
|
||||
socket = :3034
|
||||
vacuum = true
|
||||
; socket 2
|
||||
socket = pippo1.sock
|
||||
; socket 3
|
||||
socket = pippo2.sock
|
||||
; socket 4
|
||||
socket = 127.0.0.1:1717
|
||||
|
||||
map-socket = 0:1,2,3,4
|
||||
map-socket = 1:4
|
||||
map-socket = 2:10
|
||||
map-socket = 3:5,6,9
|
||||
map-socket = 4:7,8,9
|
||||
|
||||
|
||||
vacuum = true
|
||||
memory-report = true
|
||||
master = true
|
||||
processes = 10
|
||||
mount = /app1=werkzeug.testapp:test_app
|
||||
mount = /app2=config:/Users/roberta/uwsgi/my.ini
|
||||
mount = /app3=pinaxsite/deploy/pinax.wsgi
|
||||
;mount = /app1=werkzeug.testapp:test_app
|
||||
;mount = /app2=config:/Users/roberta/uwsgi/my.ini
|
||||
;mount = /app3=pinaxsite/deploy/pinax.wsgi
|
||||
|
||||
+20
-1
@@ -247,6 +247,7 @@ void erlang_loop() {
|
||||
int fd;
|
||||
|
||||
int eversion;
|
||||
int i;
|
||||
|
||||
ei_x_buff x, xr;
|
||||
|
||||
@@ -291,13 +292,31 @@ void erlang_loop() {
|
||||
|
||||
x.index = 0;
|
||||
ei_decode_version(x.buff, &x.index, &eversion);
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("eversion: %d\n", eversion);
|
||||
#endif
|
||||
|
||||
if (!strcmp(em.toname, "rex")) {
|
||||
uwsgi_erlang_rpc(fd, &em.from, &x);
|
||||
}
|
||||
else {
|
||||
dump_eterm(&x);
|
||||
int uep = -1;
|
||||
for(i=0;i<uerl.uep_cnt;i++) {
|
||||
if (!strcmp(uerl.uep[i].name, em.toname)) {
|
||||
uep = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uep > -1) {
|
||||
if (uerl.uep[uep].plugin) {
|
||||
uerl.uep[uep].plugin( uerl.uep[uep].func, &x );
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("!!! unregistered erlang process requested, dumping it !!!\n");
|
||||
dump_eterm(&x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+13
-1
@@ -1,9 +1,19 @@
|
||||
#include <ei.h>
|
||||
|
||||
#define MAX_UWSGI_ERLANG_PROCESSES 64
|
||||
|
||||
#define LONG_ARGS_ERLANG 17012
|
||||
#define LONG_ARGS_ERLANG_COOKIE 17013
|
||||
|
||||
|
||||
|
||||
struct uwsgi_erlang_process {
|
||||
|
||||
char name[0xff];
|
||||
void (*plugin)(void *, ei_x_buff *);
|
||||
void *func;
|
||||
};
|
||||
|
||||
struct uwsgi_erlang {
|
||||
|
||||
ei_cnode cnode;
|
||||
@@ -13,6 +23,8 @@ struct uwsgi_erlang {
|
||||
int fd;
|
||||
|
||||
void *lock;
|
||||
|
||||
struct uwsgi_erlang_process uep[MAX_UWSGI_ERLANG_PROCESSES];
|
||||
int uep_cnt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -345,8 +345,7 @@ void fastrouter_loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
event_queue_del_fd(fr_queue, fr_session->instance_fd);
|
||||
event_queue_add_fd_read(fr_queue, fr_session->instance_fd);
|
||||
event_queue_fd_write_to_read(fr_queue, fr_session->instance_fd);
|
||||
fr_session->status = FASTROUTER_STATUS_RESPONSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "../python/uwsgi_python.h"
|
||||
#include <greenlet/greenlet.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct ugreenlet {
|
||||
int enabled;
|
||||
PyObject *callable;
|
||||
PyGreenlet *main;
|
||||
PyGreenlet **gl;
|
||||
} ugl;
|
||||
|
||||
struct option greenlet_options[] = {
|
||||
{"greenlet", no_argument, &ugl.enabled, 1},
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
PyObject *py_uwsgi_greenlet_request(PyObject * self, PyObject *args) {
|
||||
|
||||
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req);
|
||||
uwsgi.wsgi_req->suspended = 0;
|
||||
|
||||
Py_DECREF(ugl.gl[uwsgi.wsgi_req->async_id]);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyMethodDef uwsgi_greenlet_request_method[] = {{"uwsgi_greenlet_request", py_uwsgi_greenlet_request, METH_VARARGS, ""}};
|
||||
|
||||
inline static void greenlet_schedule_to_req() {
|
||||
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
if (!uwsgi.wsgi_req->suspended) {
|
||||
ugl.gl[id] = PyGreenlet_New(ugl.callable, NULL);
|
||||
uwsgi.wsgi_req->suspended = 1;
|
||||
}
|
||||
|
||||
PyGreenlet_Switch(ugl.gl[id], NULL, NULL);
|
||||
|
||||
if (uwsgi.wsgi_req->suspended) {
|
||||
uwsgi.wsgi_req->async_status = UWSGI_AGAIN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline static void greenlet_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyGreenlet_Switch(ugl.main, NULL, NULL);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
}
|
||||
|
||||
|
||||
int greenlet_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void greenlet_init_apps(void) {
|
||||
|
||||
if (!ugl.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
PyGreenlet_Import();
|
||||
|
||||
ugl.gl = uwsgi_malloc( sizeof(PyGreenlet *) * uwsgi.async );
|
||||
ugl.main = PyGreenlet_GetCurrent();
|
||||
ugl.callable = PyCFunction_New(uwsgi_greenlet_request_method, NULL);
|
||||
uwsgi_log("enabled greenlet engine\n");
|
||||
|
||||
uwsgi.schedule_to_main = greenlet_schedule_to_main;
|
||||
uwsgi.schedule_to_req = greenlet_schedule_to_req;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_plugin greenlet_plugin = {
|
||||
|
||||
.name = "greenlet",
|
||||
.init = greenlet_init,
|
||||
.init_apps = greenlet_init_apps,
|
||||
.options = greenlet_options,
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
from distutils import sysconfig
|
||||
|
||||
NAME='greenlet'
|
||||
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['greenlet']
|
||||
+51
-3
@@ -209,7 +209,7 @@ uint16_t http_add_uwsgi_header(struct http_session *h_session, struct iovec *iov
|
||||
|
||||
for(i=0;i<hhlen;i++) {
|
||||
if (!status) {
|
||||
hh[i] = toupper(hh[i]);
|
||||
hh[i] = toupper((int)hh[i]);
|
||||
if (hh[i] == '-') hh[i] = '_';
|
||||
if (hh[i] == ':') {
|
||||
status = 1;
|
||||
@@ -501,6 +501,9 @@ void http_loop() {
|
||||
|
||||
if (interesting_fd == uhttp.server) {
|
||||
new_connection = accept(uhttp.server, (struct sockaddr *) &uhttp_addr, &uhttp_addr_len);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(uhttp_queue, uhttp.server);
|
||||
#endif
|
||||
if (new_connection < 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -531,6 +534,9 @@ void http_loop() {
|
||||
}
|
||||
else if (interesting_fd == uhttp_subserver) {
|
||||
len = recv(uhttp_subserver, bbuf, 4096, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(uhttp_queue, uhttp_subserver);
|
||||
#endif
|
||||
if (len > 0) {
|
||||
memset(&usr, 0, sizeof(struct uwsgi_subscribe_req));
|
||||
uwsgi_hooked_parse(bbuf+4, len-4, http_manage_subscription, &usr);
|
||||
@@ -548,18 +554,23 @@ void http_loop() {
|
||||
continue;
|
||||
}
|
||||
|
||||
uhttp_session->timeout = reset_timeout(uhttp_session);
|
||||
|
||||
switch(uhttp_session->status) {
|
||||
|
||||
uhttp_session->timeout = reset_timeout(uhttp_session);
|
||||
|
||||
case HTTP_STATUS_RECV:
|
||||
len = recv(uhttp_session->fd, uhttp_session->buffer + uhttp_session->h_pos, UMAX16-uhttp_session->h_pos, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(uhttp_queue, uhttp_session->fd);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
uwsgi_error("recv()");
|
||||
close_session(uhttp_table, uhttp_session);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
uhttp_session->h_pos += len;
|
||||
|
||||
for(j=0;j<len;j++) {
|
||||
@@ -681,6 +692,10 @@ void http_loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uhttp_session->uh.pktsize = uwsgi_swap16(uhttp_session->uh.pktsize);
|
||||
#endif
|
||||
|
||||
uhttp_session->iov[0].iov_base = &uhttp_session->uh;
|
||||
uhttp_session->iov[0].iov_len = 4;
|
||||
|
||||
@@ -691,7 +706,7 @@ void http_loop() {
|
||||
}
|
||||
|
||||
// fd passing: PERFORMANCE EXTREME BOOST !!!
|
||||
if (uhttp_session->pass_fd) {
|
||||
if (uhttp_session->pass_fd && !uhttp_session->remains) {
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = uhttp_session->iov;
|
||||
@@ -721,11 +736,32 @@ void http_loop() {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef __sun__
|
||||
if (uhttp_session->iov_len > IOV_MAX) {
|
||||
int remains = uhttp_session->iov_len;
|
||||
int iov_len;
|
||||
while(remains) {
|
||||
if (remains > IOV_MAX) {
|
||||
iov_len = IOV_MAX;
|
||||
}
|
||||
else {
|
||||
iov_len = remains;
|
||||
}
|
||||
if (writev(uhttp_session->instance_fd, uhttp_session->iov + (uhttp_session->iov_len-remains), iov_len) <= 0) {
|
||||
uwsgi_error("writev()");
|
||||
close_session(uhttp_table, uhttp_session);
|
||||
break;
|
||||
}
|
||||
remains -= iov_len;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (writev(uhttp_session->instance_fd, uhttp_session->iov, uhttp_session->iov_len) <= 0) {
|
||||
uwsgi_error("writev()");
|
||||
close_session(uhttp_table, uhttp_session);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
event_queue_fd_write_to_read(uhttp_queue, uhttp_session->instance_fd);
|
||||
uhttp_session->status = HTTP_STATUS_RESPONSE;
|
||||
@@ -738,6 +774,9 @@ void http_loop() {
|
||||
// data from instance
|
||||
if (interesting_fd == uhttp_session->instance_fd) {
|
||||
len = recv(uhttp_session->instance_fd, bbuf, UMAX16, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(uhttp_queue, uhttp_session->instance_fd);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
if (len < 0) uwsgi_error("recv()");
|
||||
close_session(uhttp_table, uhttp_session);
|
||||
@@ -763,6 +802,9 @@ void http_loop() {
|
||||
|
||||
//uwsgi_log("receiving body...\n");
|
||||
len = recv(uhttp_session->fd, bbuf, UMAX16, 0);
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
event_queue_add_fd_read(uhttp_queue, uhttp_session->fd);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
if (len < 0) uwsgi_error("recv()");
|
||||
close(uhttp_session->fd);
|
||||
@@ -837,6 +879,11 @@ int http_init() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uwsgi_help_item http_help[] = {
|
||||
{ "http-to <addr>", "forward http requests to uwsgi instance bound at <addr>"},
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
int http_opt(int i, char *optarg) {
|
||||
|
||||
@@ -889,6 +936,7 @@ struct uwsgi_plugin http_plugin = {
|
||||
|
||||
.options = http_options,
|
||||
.manage_opt = http_opt,
|
||||
.help = http_help,
|
||||
.init = http_init,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#undef __USE_GNU
|
||||
#include "../../uwsgi.h"
|
||||
|
||||
#include <EXTERN.h>
|
||||
|
||||
@@ -102,7 +102,7 @@ void uwsgi_psgi_app() {
|
||||
if (uperl.psgi) {
|
||||
uperl.fd = open(uperl.psgi, O_RDONLY);
|
||||
if (uperl.fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(uperl.psgi);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+51
-6
@@ -72,6 +72,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
ei_decode_string(x->buff, &x->index, atom);
|
||||
pobj = PyString_FromString(atom);
|
||||
free(atom);
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_ATOM_EXT:
|
||||
atom = uwsgi_malloc(esize+1);
|
||||
@@ -84,6 +85,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
pobj = PyUnicode_FromString(atom);
|
||||
#endif
|
||||
free(atom);
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_SMALL_TUPLE_EXT:
|
||||
case ERL_LARGE_TUPLE_EXT:
|
||||
@@ -94,6 +96,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
PyTuple_SetItem(pobj, i, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_LIST_EXT:
|
||||
case ERL_NIL_EXT:
|
||||
@@ -108,12 +111,14 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
PyList_Append(pobj, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_BINARY_EXT:
|
||||
binary = uwsgi_malloc(esize);
|
||||
ei_decode_binary(x->buff, &x->index, binary, &bin_size);
|
||||
pobj = PyString_FromStringAndSize(binary, bin_size);
|
||||
free(binary);
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
case ERL_PID_EXT:
|
||||
ei_decode_pid(x->buff, &x->index, &epid);
|
||||
@@ -121,6 +126,7 @@ PyObject *erl_to_py(ei_x_buff* x) {
|
||||
PyTuple_SetItem(pobj, 0, PyInt_FromLong(epid.num));
|
||||
PyTuple_SetItem(pobj, 1, PyInt_FromLong(epid.serial));
|
||||
PyTuple_SetItem(pobj, 2, PyInt_FromLong(epid.creation));
|
||||
Py_INCREF(pobj);
|
||||
return pobj;
|
||||
default:
|
||||
ei_skip_term(x->buff, &x->index);
|
||||
@@ -292,6 +298,42 @@ recv:
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
void pyerl_call_registered(void *func, ei_x_buff *x) {
|
||||
|
||||
PyObject *pyargs = PyTuple_New(1);
|
||||
PyObject *ret;
|
||||
|
||||
PyTuple_SetItem(pyargs, 0, erl_to_py(x));
|
||||
|
||||
ret = python_call((PyObject *) func, pyargs, 0);
|
||||
}
|
||||
|
||||
PyObject *pyerl_register_process(PyObject * self, PyObject * args) {
|
||||
|
||||
char *name;
|
||||
PyObject *callable;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO:erlang_register_process", &name, &callable)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uerl.uep_cnt >= MAX_UWSGI_ERLANG_PROCESSES)
|
||||
return PyErr_Format(PyExc_ValueError, "You can define max %d erlang registered processes", MAX_UWSGI_ERLANG_PROCESSES);
|
||||
|
||||
if (strlen(name) > 0xff-1)
|
||||
return PyErr_Format(PyExc_ValueError, "Invalid erlang process name");
|
||||
|
||||
strcpy(uerl.uep[uerl.uep_cnt].name, name);
|
||||
uerl.uep[uerl.uep_cnt].plugin = pyerl_call_registered;
|
||||
uerl.uep[uerl.uep_cnt].func = callable;
|
||||
|
||||
uerl.uep_cnt++;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
}
|
||||
|
||||
PyObject *pyerl_recv(PyObject * self, PyObject * args) {
|
||||
|
||||
ei_x_buff x;
|
||||
@@ -401,6 +443,7 @@ static PyMethodDef uwsgi_pyerl_methods[] = {
|
||||
{"erlang_rpc", pyerl_rpc, METH_VARARGS, ""},
|
||||
{"erlang_lock", pyerl_lock, METH_VARARGS, ""},
|
||||
{"erlang_unlock", pyerl_unlock, METH_VARARGS, ""},
|
||||
{"erlang_register_process", pyerl_register_process, METH_VARARGS, ""},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -426,7 +469,7 @@ int py_to_erl(PyObject *pobj, ei_x_buff *x) {
|
||||
ei_x_encode_empty_list(x);
|
||||
}
|
||||
else if (PyString_Check(pobj)) {
|
||||
ei_x_encode_string(x, PyString_AsString(pobj));
|
||||
ei_x_encode_binary(x, PyString_AsString(pobj), PyString_Size(pobj));
|
||||
}
|
||||
else if (PyUnicode_Check(pobj)) {
|
||||
ei_x_encode_atom(x, PyString_AsString(pobj));
|
||||
@@ -435,11 +478,13 @@ int py_to_erl(PyObject *pobj, ei_x_buff *x) {
|
||||
ei_x_encode_long(x, PyInt_AsLong(pobj));
|
||||
}
|
||||
else if (PyList_Check(pobj)) {
|
||||
ei_x_encode_list_header(x, PyList_Size(pobj));
|
||||
for (i = 0; i < PyList_Size(pobj); i++) {
|
||||
pobj2 = PyList_GetItem(pobj, i);
|
||||
if (py_to_erl(pobj2, x) < 0) return -1;
|
||||
}
|
||||
if (PyList_Size(pobj) > 0) {
|
||||
ei_x_encode_list_header(x, PyList_Size(pobj));
|
||||
for (i = 0; i < PyList_Size(pobj); i++) {
|
||||
pobj2 = PyList_GetItem(pobj, i);
|
||||
if (py_to_erl(pobj2, x) < 0) return -1;
|
||||
}
|
||||
}
|
||||
ei_x_encode_empty_list(x);
|
||||
}
|
||||
else if (PyTuple_Check(pobj)) {
|
||||
|
||||
+10
-1
@@ -4,13 +4,22 @@ extern struct uwsgi_server uwsgi;
|
||||
extern struct uwsgi_python up;
|
||||
|
||||
void gil_real_get() {
|
||||
#ifndef PYTHREE
|
||||
PyEval_AcquireLock();
|
||||
PyThreadState_Swap((PyThreadState *) pthread_getspecific(up.upt_gil_key));
|
||||
#else
|
||||
PyEval_RestoreThread((PyThreadState *) pthread_getspecific(up.upt_gil_key));
|
||||
#endif
|
||||
}
|
||||
|
||||
void gil_real_release() {
|
||||
#ifndef PYTHREE
|
||||
pthread_setspecific(up.upt_gil_key, (void *) PyThreadState_Swap(NULL));
|
||||
PyEval_ReleaseLock();
|
||||
PyEval_ReleaseLock();
|
||||
#else
|
||||
pthread_setspecific(up.upt_gil_key, (void *) PyThreadState_Get());
|
||||
PyEval_SaveThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
void gil_fake_get() {}
|
||||
|
||||
@@ -149,6 +149,14 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre
|
||||
wi->interpreter = up.main_thread;
|
||||
}
|
||||
|
||||
if (wsgi_req->touch_reload_len) {
|
||||
struct stat trst;
|
||||
char *touch_reload = uwsgi_strncopy(wsgi_req->touch_reload, wsgi_req->touch_reload_len);
|
||||
if (!stat(touch_reload, &trst)) {
|
||||
wi->touch_reload = touch_reload;
|
||||
wi->touch_reload_mtime = trst.st_mtime;
|
||||
}
|
||||
}
|
||||
|
||||
wi->callable = up.loaders[loader](arg1);
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ struct option uwsgi_python_options[] = {
|
||||
{"callable", required_argument, 0, LONG_ARGS_CALLABLE},
|
||||
{"test", required_argument, 0, 'j'},
|
||||
{"home", required_argument, 0, 'H'},
|
||||
{"virtualenv", required_argument, 0, 'H'},
|
||||
{"venv", required_argument, 0, 'H'},
|
||||
{"pyhome", required_argument, 0, 'H'},
|
||||
{"pythonpath", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"python-path", required_argument, 0, LONG_ARGS_PYTHONPATH},
|
||||
{"pymodule-alias", required_argument, 0, LONG_ARGS_PYMODULE_ALIAS},
|
||||
@@ -32,6 +35,29 @@ struct option uwsgi_python_options[] = {
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
struct uwsgi_help_item uwsgi_python_help[] = {
|
||||
|
||||
{"module <module>" ,"name of python config module"},
|
||||
{"optimize <n>", "set python optimization level to <n>"},
|
||||
{"home <path>", "set python home/virtualenv"},
|
||||
{"pyhome <path>", "set python home/virtualenv"},
|
||||
{"virtualenv <path>", "set python home/virtualenv"},
|
||||
{"venv <path>", "set python home/virtualenv"},
|
||||
{"callable <callable>", "set the callable (default 'application')"},
|
||||
{"paste <config:/egg:>", "load applications using paste.deploy.loadapp()"},
|
||||
{"pythonpath <dir>", "add <dir> to PYTHONPATH"},
|
||||
{"python-path <dir>", "add <dir> to PYTHONPATH"},
|
||||
{"pp <dir>", "add <dir> to PYTHONPATH"},
|
||||
{"pyargv <args>", "assign args to python sys.argv"},
|
||||
{"wsgi-file <file>", "load the <file> wsgi file"},
|
||||
{"file <file>", "use python file instead of python module for configuration"},
|
||||
{"eval <code>", "evaluate code for app configuration"},
|
||||
{"ini-paste <inifile>", "path of ini config file that contains paste configuration"},
|
||||
|
||||
|
||||
{ 0, 0},
|
||||
};
|
||||
|
||||
/* this routine will be called after each fork to reinitialize the various locks */
|
||||
void uwsgi_python_pthread_prepare(void) {
|
||||
pthread_mutex_lock(&up.lock_pyloaders);
|
||||
@@ -104,6 +130,9 @@ int uwsgi_python_init() {
|
||||
|
||||
uwsgi_log("Python main interpreter initialized at %p\n", up.main_thread);
|
||||
|
||||
// add the hacky modifier1 30
|
||||
uwsgi.p[30]->request = uwsgi.p[0]->request;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
@@ -156,36 +185,52 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
char *real_filename = filename;
|
||||
|
||||
|
||||
pyfile = fopen(filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_log("failed to open python file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(filename, "http://", 7)) {
|
||||
|
||||
if (fstat(fileno(pyfile), &pystat)) {
|
||||
uwsgi_error("fstat()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (S_ISDIR(pystat.st_mode)) {
|
||||
is_a_package = 1;
|
||||
fclose(pyfile);
|
||||
real_filename = uwsgi_concat2(filename, "/__init__.py");
|
||||
pyfile = fopen(real_filename, "r");
|
||||
pyfile = fopen(filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_error("fopen()");
|
||||
uwsgi_log("failed to open python file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
if (fstat(fileno(pyfile), &pystat)) {
|
||||
uwsgi_error("fstat()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(pyfile);
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
py_compiled_node = (PyObject *) PyNode_Compile(py_file_node, real_filename);
|
||||
|
||||
@@ -687,6 +732,11 @@ int uwsgi_python_mount_app(char *mountpoint, char *app) {
|
||||
|
||||
void uwsgi_python_init_apps() {
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
|
||||
up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async);
|
||||
}
|
||||
|
||||
init_pyargv();
|
||||
#ifdef UWSGI_MINTERPRETERS
|
||||
init_uwsgi_embedded_module();
|
||||
@@ -795,6 +845,9 @@ int uwsgi_python_xml(char *node, char *content) {
|
||||
uwsgi.wsgi_req->module_len = strlen(uwsgi.wsgi_req->module);
|
||||
return init_uwsgi_app(LOADER_DYN, uwsgi.wsgi_req, uwsgi.wsgi_req, interpreter);
|
||||
}
|
||||
else {
|
||||
return init_uwsgi_app(LOADER_UWSGI, content, uwsgi.wsgi_req, interpreter);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp("pyhome", node)) {
|
||||
@@ -815,9 +868,14 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
|
||||
uwsgi_log("suspending python\n");
|
||||
up.current_recursion_depth = tstate->recursion_depth;
|
||||
up.current_frame = tstate->frame;
|
||||
if (wsgi_req) {
|
||||
up.current_recursion_depth[wsgi_req->async_id] = tstate->recursion_depth;
|
||||
up.current_frame[wsgi_req->async_id] = tstate->frame;
|
||||
}
|
||||
else {
|
||||
up.current_main_recursion_depth = tstate->recursion_depth;
|
||||
up.current_main_frame = tstate->frame;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -829,6 +887,9 @@ int uwsgi_python_signal_handler(uint8_t sig, void *handler) {
|
||||
if (!args)
|
||||
return -1;
|
||||
|
||||
if (!handler) return -1;
|
||||
|
||||
|
||||
PyTuple_SetItem(args, 0, PyInt_FromLong(sig));
|
||||
|
||||
ret = python_call(handler, args, 0);
|
||||
@@ -929,9 +990,14 @@ void uwsgi_python_resume(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
|
||||
uwsgi_log("resuming python\n");
|
||||
tstate->recursion_depth = up.current_recursion_depth;
|
||||
tstate->frame = up.current_frame;
|
||||
if (wsgi_req) {
|
||||
tstate->recursion_depth = up.current_recursion_depth[wsgi_req->async_id];
|
||||
tstate->frame = up.current_frame[wsgi_req->async_id];
|
||||
}
|
||||
else {
|
||||
tstate->recursion_depth = up.current_main_recursion_depth;
|
||||
tstate->frame = up.current_main_frame;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -963,8 +1029,7 @@ struct uwsgi_plugin python_plugin = {
|
||||
.rpc = uwsgi_python_rpc,
|
||||
|
||||
.spooler = uwsgi_python_spooler,
|
||||
/*
|
||||
.help = uwsgi_python_help,
|
||||
*/
|
||||
|
||||
.help = uwsgi_python_help,
|
||||
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ extern struct uwsgi_python up;
|
||||
|
||||
int manage_python_response(struct wsgi_request *wsgi_req) {
|
||||
// use standard WSGI response parse
|
||||
wsgi_req->switches++;
|
||||
return uwsgi_response_subhandler_wsgi(wsgi_req);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,6 +181,25 @@ PyObject *py_uwsgi_close(PyObject * self, PyObject * args) {
|
||||
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_add_cron(PyObject * self, PyObject * args) {
|
||||
|
||||
uint8_t uwsgi_signal;
|
||||
int minute, hour, day, month, week;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "Biiiii:add_cron", &uwsgi_signal, &minute, &hour, &day, &month, &week)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi_signal_add_cron(uwsgi_signal, minute, hour, day, month, week)) {
|
||||
return PyErr_Format(PyExc_ValueError, "unable to add cron");
|
||||
}
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject *py_uwsgi_add_timer(PyObject * self, PyObject * args) {
|
||||
|
||||
uint8_t uwsgi_signal;
|
||||
@@ -794,16 +813,16 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
|
||||
PyObject *py_uwsgi_async_sleep(PyObject * self, PyObject * args) {
|
||||
|
||||
float timeout;
|
||||
time_t sec_timeout;
|
||||
int sec_timeout;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "f:async_sleep", &timeout)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sec_timeout = (time_t) timeout;
|
||||
sec_timeout = (int) timeout;
|
||||
|
||||
if (sec_timeout > 0) {
|
||||
async_set_timeout(uwsgi.wsgi_req, sec_timeout);
|
||||
async_add_timeout(uwsgi.wsgi_req, sec_timeout);
|
||||
}
|
||||
|
||||
return PyString_FromString("");
|
||||
@@ -2068,7 +2087,7 @@ PyObject *py_uwsgi_parse_file(PyObject * self, PyObject * args) {
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(filename);
|
||||
goto clear;
|
||||
}
|
||||
|
||||
@@ -2223,7 +2242,7 @@ PyObject *py_uwsgi_suspend(PyObject * self, PyObject * args) {
|
||||
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
|
||||
uwsgi.schedule_to_main(wsgi_req);
|
||||
if (uwsgi.schedule_to_main) uwsgi.schedule_to_main(wsgi_req);
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
return Py_True;
|
||||
@@ -2343,6 +2362,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
|
||||
{"add_file_monitor", py_uwsgi_add_file_monitor, METH_VARARGS, ""},
|
||||
{"add_timer", py_uwsgi_add_timer, METH_VARARGS, ""},
|
||||
{"add_rb_timer", py_uwsgi_add_rb_timer, METH_VARARGS, ""},
|
||||
{"add_cron", py_uwsgi_add_cron, METH_VARARGS, ""},
|
||||
|
||||
{"register_rpc", py_uwsgi_register_rpc, METH_VARARGS, ""},
|
||||
{"rpc", py_uwsgi_rpc, METH_VARARGS, ""},
|
||||
@@ -2508,7 +2528,6 @@ PyObject *py_uwsgi_queue_push(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
if (uwsgi.queue_size) {
|
||||
uwsgi_log("locking queue\n");
|
||||
uwsgi_wlock(uwsgi.queue_lock);
|
||||
if (uwsgi_queue_push(message, msglen)) {
|
||||
Py_INCREF(Py_True);
|
||||
@@ -2519,7 +2538,6 @@ PyObject *py_uwsgi_queue_push(PyObject * self, PyObject * args) {
|
||||
res = Py_None;
|
||||
}
|
||||
uwsgi_rwunlock(uwsgi.queue_lock);
|
||||
uwsgi_log("unlocked queue\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -2591,6 +2609,56 @@ PyObject *py_uwsgi_queue_get(PyObject * self, PyObject * args) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_queue_last(PyObject * self, PyObject * args) {
|
||||
|
||||
long num = 0;
|
||||
uint64_t size = 0;
|
||||
char *message;
|
||||
PyObject *res, *zero;
|
||||
uint64_t base;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "l:queue_last", &num)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uwsgi.queue_size) {
|
||||
res = PyList_New(0);
|
||||
uwsgi_rlock(uwsgi.queue_lock);
|
||||
if (uwsgi.shared->queue_pos > 0) {
|
||||
base = uwsgi.shared->queue_pos-1;
|
||||
}
|
||||
else {
|
||||
base = uwsgi.queue_size-1;
|
||||
}
|
||||
if (num > (long)uwsgi.queue_size) num = uwsgi.queue_size;
|
||||
while(num) {
|
||||
message = uwsgi_queue_get(base, &size);
|
||||
if (message && size) {
|
||||
zero = PyString_FromStringAndSize(message, size);
|
||||
PyList_Append(res, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
else {
|
||||
uwsgi_rwunlock(uwsgi.queue_lock);
|
||||
return res;
|
||||
}
|
||||
if (base > 0) {
|
||||
base--;
|
||||
}
|
||||
else {
|
||||
base = uwsgi.queue_size-1;
|
||||
}
|
||||
num--;
|
||||
}
|
||||
uwsgi_rwunlock(uwsgi.queue_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
||||
|
||||
char *key;
|
||||
@@ -2621,6 +2689,11 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
|
||||
#endif
|
||||
uwsgi_rlock(uwsgi.cache_lock);
|
||||
value = uwsgi_cache_get(key, keylen, &valsize);
|
||||
if (!value) {
|
||||
uwsgi_rwunlock(uwsgi.cache_lock);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
res = PyString_FromStringAndSize(value, valsize);
|
||||
#ifdef UWSGI_DEBUG
|
||||
gettimeofday(&tv2, NULL);
|
||||
@@ -2651,6 +2724,7 @@ static PyMethodDef uwsgi_cache_methods[] = {
|
||||
|
||||
static PyMethodDef uwsgi_queue_methods[] = {
|
||||
{"queue_get", py_uwsgi_queue_get, METH_VARARGS, ""},
|
||||
{"queue_last", py_uwsgi_queue_last, METH_VARARGS, ""},
|
||||
{"queue_push", py_uwsgi_queue_push, METH_VARARGS, ""},
|
||||
{"queue_pull", py_uwsgi_queue_pull, METH_VARARGS, ""},
|
||||
{"queue_slot", py_uwsgi_queue_slot, METH_VARARGS, ""},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <Python.h>
|
||||
|
||||
#include <frameobject.h>
|
||||
|
||||
#define MAX_PYTHONPATH 64
|
||||
#define MAX_PYMODULE_ALIAS 64
|
||||
@@ -13,10 +14,6 @@
|
||||
#define LONG_ARGS_PYMODULE_ALIAS LONG_ARGS_PYTHON_BASE + 4
|
||||
#define LONG_ARGS_RELOAD_OS_ENV LONG_ARGS_PYTHON_BASE + 5
|
||||
|
||||
#ifdef UWSGI_STACKLESS
|
||||
#include <stackless_api.h>
|
||||
#endif
|
||||
|
||||
#if PY_MINOR_VERSION == 4 && PY_MAJOR_VERSION == 2
|
||||
#define Py_ssize_t ssize_t
|
||||
#endif
|
||||
@@ -110,8 +107,11 @@ struct uwsgi_python {
|
||||
int ignore_script_name;
|
||||
int catch_exceptions;
|
||||
|
||||
int current_recursion_depth;
|
||||
struct _frame* current_frame;
|
||||
int *current_recursion_depth;
|
||||
struct _frame **current_frame;
|
||||
|
||||
int current_main_recursion_depth;
|
||||
struct _frame *current_main_frame;
|
||||
|
||||
void (*swap_ts)(struct wsgi_request *, struct uwsgi_app *);
|
||||
void (*reset_ts)(struct wsgi_request *, struct uwsgi_app *);
|
||||
@@ -157,10 +157,6 @@ PyObject *py_eventfd_read(PyObject *, PyObject *);
|
||||
PyObject *py_eventfd_write(PyObject *, PyObject *);
|
||||
|
||||
|
||||
#ifdef UWSGI_STACKLESS
|
||||
PyObject *py_uwsgi_stackless(PyObject *, PyObject *);
|
||||
#endif
|
||||
|
||||
int manage_python_response(struct wsgi_request *);
|
||||
int uwsgi_python_call(struct wsgi_request *, PyObject *, PyObject *);
|
||||
PyObject *python_call(PyObject *, PyObject *, int);
|
||||
@@ -174,18 +170,6 @@ ssize_t uwsgi_do_sendfile(int, int, size_t, size_t, off_t*, int);
|
||||
PyObject *py_uwsgi_write(PyObject *, PyObject *);
|
||||
PyObject *py_uwsgi_spit(PyObject *, PyObject *);
|
||||
|
||||
#ifdef UWSGI_STACKLESS
|
||||
struct stackless_req {
|
||||
PyTaskletObject *tasklet;
|
||||
struct wsgi_request *wsgi_req;
|
||||
PyChannelObject *channel;
|
||||
};
|
||||
struct wsgi_request *find_request_by_tasklet(PyTaskletObject *);
|
||||
|
||||
void stackless_init(void);
|
||||
void stackless_loop(void);
|
||||
#endif
|
||||
|
||||
void init_pyargv(void);
|
||||
|
||||
#ifdef UWSGI_WEB3
|
||||
|
||||
@@ -20,10 +20,12 @@ else:
|
||||
os.environ['LD_RUN_PATH'] = "%s/lib" % sysconfig.PREFIX
|
||||
|
||||
|
||||
version = sys.version_info
|
||||
uver = "%d.%d" % (version[0], version[1])
|
||||
|
||||
LIBS.append('-lpython' + uver)
|
||||
version = sysconfig.get_config_var('VERSION')
|
||||
try:
|
||||
version = version + sys.abiflags
|
||||
except:
|
||||
pass
|
||||
LIBS.append('-lpython' + version)
|
||||
|
||||
#if str(PYLIB_PATH) != '':
|
||||
# libs.insert(0,'-L' + PYLIB_PATH)
|
||||
|
||||
@@ -17,9 +17,8 @@ PyObject *uwsgi_Input_iter(PyObject * self) {
|
||||
|
||||
PyObject *uwsgi_Input_next(PyObject * self) {
|
||||
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return PyErr_Format(PyExc_NotImplementedError, "wsgi.input __iter__() is not implemented");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void uwsgi_Input_free(uwsgi_Input *self) {
|
||||
@@ -29,7 +28,7 @@ static void uwsgi_Input_free(uwsgi_Input *self) {
|
||||
static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
|
||||
long len = 0;
|
||||
size_t remains, chunk_size;
|
||||
size_t remains;
|
||||
ssize_t rlen;
|
||||
char *tmp_buf;
|
||||
int fd;
|
||||
@@ -75,27 +74,22 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
return res;
|
||||
}
|
||||
|
||||
chunk_size = remains;
|
||||
tmp_buf = uwsgi_malloc(remains);
|
||||
while(remains) {
|
||||
if (uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) {
|
||||
free(tmp_buf);
|
||||
return PyErr_Format(PyExc_ValueError, "error waiting for wsgi.input data");
|
||||
}
|
||||
|
||||
rlen = read(fd, tmp_buf + self->pos, remains);
|
||||
if (rlen < 0) {
|
||||
free(tmp_buf);
|
||||
return PyErr_Format(PyExc_ValueError, "error reading wsgi.input data");
|
||||
}
|
||||
|
||||
if (!rlen) break;
|
||||
|
||||
self->pos += rlen;
|
||||
remains -= rlen;
|
||||
if (uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) {
|
||||
free(tmp_buf);
|
||||
return PyErr_Format(PyExc_IOError, "error waiting for wsgi.input data");
|
||||
}
|
||||
|
||||
res = PyString_FromStringAndSize(tmp_buf, chunk_size);
|
||||
rlen = read(fd, tmp_buf, remains);
|
||||
if (rlen < 0) {
|
||||
free(tmp_buf);
|
||||
return PyErr_Format(PyExc_IOError, "error reading wsgi.input data");
|
||||
}
|
||||
|
||||
self->pos += rlen;
|
||||
res = PyString_FromStringAndSize(tmp_buf, rlen);
|
||||
|
||||
free(tmp_buf);
|
||||
return res;
|
||||
|
||||
@@ -103,17 +97,19 @@ static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {
|
||||
|
||||
static PyObject *uwsgi_Input_readline(uwsgi_Input *self, PyObject *args) {
|
||||
|
||||
return NULL;
|
||||
return PyErr_Format(PyExc_NotImplementedError, "wsgi.input readline() is not implemented");
|
||||
|
||||
}
|
||||
|
||||
static PyObject *uwsgi_Input_readlines(uwsgi_Input *self, PyObject *args) {
|
||||
|
||||
return NULL;
|
||||
return PyErr_Format(PyExc_NotImplementedError, "wsgi.input readlines() is not implemented");
|
||||
}
|
||||
|
||||
static PyObject *uwsgi_Input_close(uwsgi_Input *self, PyObject *args) {
|
||||
|
||||
return NULL;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyMethodDef uwsgi_Input_methods[] = {
|
||||
@@ -196,12 +192,7 @@ PyObject *py_eventfd_read(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
wsgi_req->async_waiting_fd = fd;
|
||||
wsgi_req->async_waiting_fd_type = ASYNC_IN;
|
||||
wsgi_req->async_waiting_fd_monitored = 0;
|
||||
if (timeout > 0) {
|
||||
wsgi_req->async_timeout = time(NULL) + timeout;
|
||||
}
|
||||
async_add_fd_read(wsgi_req, fd, timeout);
|
||||
}
|
||||
|
||||
return PyString_FromString("");
|
||||
@@ -218,12 +209,7 @@ PyObject *py_eventfd_write(PyObject * self, PyObject * args) {
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
wsgi_req->async_waiting_fd = fd;
|
||||
wsgi_req->async_waiting_fd_type = ASYNC_OUT;
|
||||
wsgi_req->async_waiting_fd_monitored = 0;
|
||||
if (timeout > 0) {
|
||||
wsgi_req->async_timeout = time(NULL) + timeout;
|
||||
}
|
||||
async_add_fd_write(wsgi_req, fd, timeout);
|
||||
}
|
||||
|
||||
return PyString_FromString("");
|
||||
@@ -249,13 +235,21 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
// get rid of timeout
|
||||
if (wsgi_req->async_timeout_expired) {
|
||||
if (wsgi_req->async_timed_out) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_True);
|
||||
wsgi_req->async_timeout_expired = 0;
|
||||
wsgi_req->async_timed_out = 0;
|
||||
}
|
||||
else {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "x-wsgiorg.fdevent.timeout", Py_None);
|
||||
}
|
||||
|
||||
if (wsgi_req->async_ready_fd) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.ready_fd", PyInt_FromLong(wsgi_req->async_last_ready_fd));
|
||||
wsgi_req->async_ready_fd = 0;
|
||||
}
|
||||
else {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.ready_fd", Py_None);
|
||||
}
|
||||
return manage_python_response(wsgi_req);
|
||||
}
|
||||
#endif
|
||||
@@ -268,7 +262,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
uwsgi_log("Invalid WSGI request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -398,8 +391,8 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_debug("%.*s: %.*s\n", wsgi_req->hvec[i].iov_len, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i+1].iov_len, wsgi_req->hvec[i+1].iov_base);
|
||||
#endif
|
||||
#ifdef PYTHREE
|
||||
pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, "ignore");
|
||||
pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, "ignore");
|
||||
pydictkey = PyUnicode_DecodeLatin1(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, NULL);
|
||||
pydictvalue = PyUnicode_DecodeLatin1(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len, NULL);
|
||||
#else
|
||||
pydictkey = PyString_FromStringAndSize(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len);
|
||||
pydictvalue = PyString_FromStringAndSize(wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
|
||||
@@ -428,15 +421,29 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (uwsgi.post_buffering > 0) {
|
||||
UWSGI_RELEASE_GIL
|
||||
// read to disk
|
||||
if (wsgi_req->post_cl <= (size_t) uwsgi.post_buffering) {
|
||||
if (!uwsgi_read_whole_body(wsgi_req, wsgi_req->post_buffering_buf, uwsgi.post_buffering_bufsize)) {
|
||||
goto clear;
|
||||
// read to disk if post_cl > post_buffering
|
||||
if (!up.pep3333_input) {
|
||||
if (wsgi_req->post_cl >= (size_t) uwsgi.post_buffering) {
|
||||
if (!uwsgi_read_whole_body(wsgi_req, wsgi_req->post_buffering_buf, uwsgi.post_buffering_bufsize)) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wsgi_req->async_post = fdopen(wsgi_req->poll.fd, "r");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!uwsgi_read_whole_body_in_mem(wsgi_req, wsgi_req->post_buffering_buf)) {
|
||||
goto clear;
|
||||
// read to disk if post_cl > post_buffering
|
||||
if (wsgi_req->post_cl >= (size_t) uwsgi.post_buffering) {
|
||||
if (!uwsgi_read_whole_body(wsgi_req, wsgi_req->post_buffering_buf, uwsgi.post_buffering_bufsize)) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
// on tiny post use memory
|
||||
else {
|
||||
if (!uwsgi_read_whole_body_in_mem(wsgi_req, wsgi_req->post_buffering_buf)) {
|
||||
goto clear;
|
||||
}
|
||||
}
|
||||
}
|
||||
UWSGI_GET_GIL
|
||||
@@ -467,11 +474,15 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
while (wi->response_subhandler(wsgi_req) != UWSGI_OK) {
|
||||
wsgi_req->switches++;
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi.async > 1) {
|
||||
return UWSGI_AGAIN;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
wsgi_req->switches++;
|
||||
#ifdef UWSGI_ASYNC
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[2].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uh.pktsize += wsgi_req->hvec[2].iov_len;
|
||||
wsgi_req->status = atoi(wsgi_req->hvec[2].iov_base);
|
||||
wsgi_req->status = uwsgi_str3_num(wsgi_req->hvec[2].iov_base);
|
||||
wsgi_req->hvec[3].iov_base = nl;
|
||||
wsgi_req->hvec[3].iov_len = NL_SIZE;
|
||||
uh.pktsize += wsgi_req->hvec[3].iov_len;
|
||||
@@ -87,7 +87,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
|
||||
wsgi_req->hvec[1].iov_len = PyString_Size(head);
|
||||
#endif
|
||||
uh.pktsize += wsgi_req->hvec[1].iov_len;
|
||||
wsgi_req->status = atoi(wsgi_req->hvec[1].iov_base);
|
||||
wsgi_req->status = uwsgi_str3_num(wsgi_req->hvec[1].iov_base);
|
||||
wsgi_req->hvec[2].iov_base = nl;
|
||||
wsgi_req->hvec[2].iov_len = NL_SIZE;
|
||||
uh.pktsize += wsgi_req->hvec[2].iov_len;
|
||||
|
||||
@@ -225,18 +225,6 @@ clear2:
|
||||
Py_DECREF((PyObject *)wsgi_req->async_result);
|
||||
PyErr_Clear();
|
||||
|
||||
#ifdef UWSGI_DEBUG
|
||||
if (wsgi_req->async_placeholder) {
|
||||
uwsgi_debug("wsgi_req->async_placeholder: %d\n", ((PyObject *)wsgi_req->async_placeholder)->ob_refcnt);
|
||||
}
|
||||
if (wsgi_req->async_result) {
|
||||
uwsgi_debug("wsgi_req->async_result: %d\n", ((PyObject *)wsgi_req->async_result)->ob_refcnt);
|
||||
}
|
||||
if (wsgi_req->async_app) {
|
||||
uwsgi_debug("wsgi_req->async_app: %d\n", ((PyObject *)wsgi_req->async_app)->ob_refcnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
UWSGI_RELEASE_GIL
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
@@ -94,14 +94,12 @@ VALUE protected_fiber_loop() {
|
||||
if (!wsgi_req) goto cycle;
|
||||
uwsgi_log("request passed to fiber core %d\n", wsgi_req->async_id);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
uwsgi.wsgi_req->switches++;
|
||||
rb_fiber_resume(fiber_list[wsgi_req->async_id], 0, NULL);
|
||||
}
|
||||
else {
|
||||
wsgi_req = find_wsgi_req_by_fd((int)uwsgi.async_events[i].ASYNC_FD, -1);
|
||||
if (wsgi_req) {
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
uwsgi.wsgi_req->switches++;
|
||||
rb_fiber_resume(fiber_list[wsgi_req->async_id], 0, NULL);
|
||||
}
|
||||
else {
|
||||
@@ -116,7 +114,6 @@ cycle:
|
||||
|
||||
//uwsgi_log("resuming fiber %d %p\n", current, fiber_list[current]);
|
||||
uwsgi.wsgi_req = uwsgi.wsgi_requests[current];
|
||||
uwsgi.wsgi_req->switches++;
|
||||
if (uwsgi.wsgi_req->async_status != UWSGI_ACCEPTING) {
|
||||
uwsgi_log("passing control to fiber %d\n", current);
|
||||
rb_fiber_resume(fiber_list[current], 0, NULL);
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "../python/uwsgi_python.h"
|
||||
#include <stackless_api.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct ustackless {
|
||||
int enabled;
|
||||
PyObject *callable;
|
||||
PyTaskletObject **sl;
|
||||
} usl;
|
||||
|
||||
struct option stackless_options[] = {
|
||||
{"stackless", no_argument, &usl.enabled, 1},
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
PyObject *py_uwsgi_stackless_request(PyObject * self, PyObject *args) {
|
||||
|
||||
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req);
|
||||
uwsgi.wsgi_req->suspended = 0;
|
||||
|
||||
Py_DECREF(usl.sl[uwsgi.wsgi_req->async_id]);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyMethodDef uwsgi_stackless_request_method[] = {{"uwsgi_stackless_request", py_uwsgi_stackless_request, METH_VARARGS, ""}};
|
||||
|
||||
inline static void stackless_schedule_to_req() {
|
||||
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
if (!uwsgi.wsgi_req->suspended) {
|
||||
usl.sl[id] = PyTasklet_New(NULL, usl.callable);
|
||||
PyObject *args = PyTuple_New(0);
|
||||
PyTasklet_Setup(usl.sl[id], args, NULL);
|
||||
Py_DECREF(args);
|
||||
uwsgi.wsgi_req->suspended = 1;
|
||||
}
|
||||
|
||||
PyTasklet_Run(usl.sl[id]);
|
||||
|
||||
if (uwsgi.wsgi_req->suspended) {
|
||||
uwsgi.wsgi_req->async_status = UWSGI_AGAIN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline static void stackless_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
PyStackless_Schedule(Py_None, 1);
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
}
|
||||
|
||||
|
||||
int stackless_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stackless_init_apps(void) {
|
||||
|
||||
if (!usl.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
usl.sl = uwsgi_malloc( sizeof(PyTaskletObject *) * uwsgi.async );
|
||||
usl.callable = PyCFunction_New(uwsgi_stackless_request_method, NULL);
|
||||
uwsgi_log("enabled stackless engine\n");
|
||||
uwsgi.schedule_to_main = stackless_schedule_to_main;
|
||||
uwsgi.schedule_to_req = stackless_schedule_to_req;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
struct uwsgi_plugin stackless_plugin = {
|
||||
|
||||
.name = "stackless",
|
||||
.init = stackless_init,
|
||||
.init_apps = stackless_init_apps,
|
||||
.options = stackless_options,
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
from distutils import sysconfig
|
||||
|
||||
NAME='stackless'
|
||||
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['stackless']
|
||||
+41
-274
@@ -12,7 +12,7 @@ struct uwsgi_ugreen {
|
||||
int ugreen;
|
||||
int stackpages;
|
||||
ucontext_t main;
|
||||
ucontext_t **contexts;
|
||||
ucontext_t *contexts;
|
||||
size_t u_stack_size;
|
||||
} ug;
|
||||
|
||||
@@ -27,165 +27,60 @@ struct option ugreen_options[] = {
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
void u_green_loop(void);
|
||||
|
||||
void u_green_write_all(char *data, size_t len) {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
int i;
|
||||
ssize_t rlen;
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_status == UWSGI_PAUSED) {
|
||||
rlen = write(wsgi_req->poll.fd, data, len);
|
||||
if (rlen < 0) {
|
||||
uwsgi_error("write()");
|
||||
// mark core as plagued
|
||||
wsgi_req->async_plagued = 1;
|
||||
}
|
||||
else {
|
||||
wsgi_req->response_size += rlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
void u_green_request() {
|
||||
uwsgi.wsgi_req->async_status = uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->request(uwsgi.wsgi_req);
|
||||
uwsgi.wsgi_req->suspended = 0;
|
||||
}
|
||||
|
||||
void u_green_unpause_all() {
|
||||
inline static void u_green_schedule_to_req() {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
int i;
|
||||
int id = uwsgi.wsgi_req->async_id;
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_status == UWSGI_PAUSED) {
|
||||
wsgi_req->async_status = UWSGI_AGAIN;
|
||||
wsgi_req->async_timeout = 0;
|
||||
}
|
||||
if (!uwsgi.wsgi_req->suspended) {
|
||||
ug.contexts[id].uc_link = &ug.main;
|
||||
makecontext(&ug.contexts[id], u_green_request, 0);
|
||||
uwsgi.wsgi_req->suspended = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->suspend) {
|
||||
uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->suspend(NULL);
|
||||
}
|
||||
|
||||
swapcontext(&ug.main, &ug.contexts[id] );
|
||||
|
||||
static int u_green_blocking() {
|
||||
struct wsgi_request* wsgi_req;
|
||||
int i;
|
||||
if (uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->resume) {
|
||||
uwsgi.p[uwsgi.wsgi_req->uh.modifier1]->resume(NULL);
|
||||
}
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_status != UWSGI_ACCEPTING && wsgi_req->async_status != UWSGI_PAUSED && wsgi_req->async_waiting_fd == -1 && !wsgi_req->async_timeout) {
|
||||
return 0;
|
||||
}
|
||||
if (uwsgi.wsgi_req->suspended) {
|
||||
uwsgi.wsgi_req->async_status = UWSGI_AGAIN;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline static void u_green_schedule_to_main(struct wsgi_request *wsgi_req) {
|
||||
|
||||
if (wsgi_req->async_status != UWSGI_ACCEPTING) {
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->suspend) {
|
||||
uwsgi.p[wsgi_req->uh.modifier1]->suspend(wsgi_req);
|
||||
}
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->suspend) {
|
||||
uwsgi.p[wsgi_req->uh.modifier1]->suspend(wsgi_req);
|
||||
}
|
||||
|
||||
uwsgi_log("uGreen EXITING TO MAIN\n");
|
||||
swapcontext(ug.contexts[wsgi_req->async_id], &ug.main);
|
||||
swapcontext(&ug.contexts[wsgi_req->async_id], &ug.main);
|
||||
|
||||
uwsgi_log("uGreen RETURNED FROM MAIN\n");
|
||||
|
||||
if (wsgi_req->async_status != UWSGI_ACCEPTING) {
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->resume) {
|
||||
uwsgi.p[wsgi_req->uh.modifier1]->resume(wsgi_req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static void u_green_schedule_to_req(struct wsgi_request *wsgi_req) {
|
||||
|
||||
|
||||
if (wsgi_req->async_status != UWSGI_ACCEPTING) {
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->suspend) {
|
||||
uwsgi.p[wsgi_req->uh.modifier1]->suspend(wsgi_req);
|
||||
}
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->resume) {
|
||||
uwsgi.p[wsgi_req->uh.modifier1]->resume(wsgi_req);
|
||||
}
|
||||
|
||||
uwsgi.wsgi_req = wsgi_req;
|
||||
uwsgi_log("SWAPCONTEXT to %p\n", ug.contexts[wsgi_req->async_id]);
|
||||
//wsgi_req->async_switches++;
|
||||
swapcontext(&ug.main, ug.contexts[wsgi_req->async_id] );
|
||||
|
||||
uwsgi_log("RESUMED\n");
|
||||
|
||||
if (wsgi_req->async_status != UWSGI_ACCEPTING) {
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->resume) {
|
||||
uwsgi.p[wsgi_req->uh.modifier1]->resume(wsgi_req);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void u_green_wait_for_fd(struct wsgi_request *wsgi_req, int fd, int etype, int timeout) {
|
||||
|
||||
if (fd < 0) return;
|
||||
|
||||
if (async_add(uwsgi.async_queue, fd, etype)) return;
|
||||
|
||||
wsgi_req->async_waiting_fd = fd;
|
||||
wsgi_req->async_waiting_fd_type = etype;
|
||||
wsgi_req->async_timeout = time(NULL) + timeout;
|
||||
|
||||
u_green_schedule_to_main(wsgi_req);
|
||||
|
||||
async_del(uwsgi.async_queue, wsgi_req->async_waiting_fd, wsgi_req->async_waiting_fd_type);
|
||||
|
||||
wsgi_req->async_waiting_fd = -1;
|
||||
wsgi_req->async_timeout = 0;
|
||||
}
|
||||
|
||||
static void u_green_request(struct wsgi_request *wsgi_req, int async_id) {
|
||||
|
||||
uwsgi_log("request handler args %p %d\n", wsgi_req, async_id);
|
||||
|
||||
for(;;) {
|
||||
uwsgi_log("accept()\n");
|
||||
wsgi_req_setup(wsgi_req, async_id);
|
||||
|
||||
wsgi_req->async_status = UWSGI_ACCEPTING;
|
||||
|
||||
u_green_schedule_to_main(wsgi_req);
|
||||
|
||||
if (wsgi_req_accept(wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uwsgi_log("REQUEST ACCEPTED\n");
|
||||
wsgi_req->async_status = UWSGI_OK;
|
||||
|
||||
// check here
|
||||
//u_green_schedule_to_main(wsgi_req);
|
||||
|
||||
if (wsgi_req_recv(wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while(wsgi_req->async_status == UWSGI_AGAIN) {
|
||||
u_green_schedule_to_main(wsgi_req);
|
||||
wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req);
|
||||
}
|
||||
|
||||
u_green_schedule_to_main(wsgi_req);
|
||||
|
||||
uwsgi_close_request(wsgi_req);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int u_green_init() {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
static int i;
|
||||
|
||||
volatile int i;
|
||||
if (!ug.ugreen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ug.u_stack_size = UGREEN_DEFAULT_STACKSIZE;
|
||||
|
||||
@@ -196,168 +91,38 @@ int u_green_init() {
|
||||
uwsgi_log("initializing %d uGreen threads with stack size of %lu (%lu KB)\n", uwsgi.async, (unsigned long) ug.u_stack_size, (unsigned long) ug.u_stack_size/1024);
|
||||
|
||||
|
||||
ug.contexts = malloc( sizeof(ucontext_t*) * uwsgi.async);
|
||||
if (!ug.contexts) {
|
||||
uwsgi_error("malloc()\n");
|
||||
exit(1);
|
||||
}
|
||||
ug.contexts = uwsgi_malloc( sizeof(ucontext_t) * uwsgi.async);
|
||||
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
ug.contexts[i] = malloc( sizeof(ucontext_t) );
|
||||
if (!ug.contexts[i]) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
getcontext(ug.contexts[i]);
|
||||
|
||||
ug.contexts[i]->uc_stack.ss_sp = mmap(NULL, ug.u_stack_size + (uwsgi.page_size*2) , PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0) + uwsgi.page_size;
|
||||
getcontext(&ug.contexts[i]);
|
||||
|
||||
if (!ug.contexts[i]->uc_stack.ss_sp) {
|
||||
ug.contexts[i].uc_stack.ss_sp = mmap(NULL, ug.u_stack_size + (uwsgi.page_size*2) , PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0) + uwsgi.page_size;
|
||||
|
||||
if (!ug.contexts[i].uc_stack.ss_sp) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
// set guard pages for stack
|
||||
if (mprotect(ug.contexts[i]->uc_stack.ss_sp - uwsgi.page_size, uwsgi.page_size, PROT_NONE)) {
|
||||
if (mprotect(ug.contexts[i].uc_stack.ss_sp - uwsgi.page_size, uwsgi.page_size, PROT_NONE)) {
|
||||
uwsgi_error("mprotect()");
|
||||
exit(1);
|
||||
}
|
||||
if (mprotect(ug.contexts[i]->uc_stack.ss_sp + ug.u_stack_size, uwsgi.page_size, PROT_NONE)) {
|
||||
if (mprotect(ug.contexts[i].uc_stack.ss_sp + ug.u_stack_size, uwsgi.page_size, PROT_NONE)) {
|
||||
uwsgi_error("mprotect()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ug.contexts[i]->uc_stack.ss_size = ug.u_stack_size;
|
||||
ug.contexts[i].uc_stack.ss_size = ug.u_stack_size;
|
||||
|
||||
ug.contexts[i]->uc_link = NULL;
|
||||
makecontext(ug.contexts[i], (void(*)(void)) u_green_request, 2, wsgi_req, i);
|
||||
wsgi_req->async_status = UWSGI_ACCEPTING;
|
||||
wsgi_req->async_id = i;
|
||||
uwsgi_log("wsgi_req %d %d %p\n", wsgi_req->async_id, wsgi_req->async_status, ug.contexts[i]);
|
||||
}
|
||||
|
||||
uwsgi_register_loop("ugreen", u_green_loop);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void u_green_expire_timeouts() {
|
||||
|
||||
struct wsgi_request* wsgi_req;
|
||||
int i;
|
||||
time_t deadline = time(NULL);
|
||||
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_timeout > 0) {
|
||||
if (wsgi_req->async_timeout <= deadline) {
|
||||
wsgi_req->async_status = UWSGI_AGAIN;
|
||||
wsgi_req->async_timeout = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int u_green_get_timeout() {
|
||||
|
||||
|
||||
struct wsgi_request* wsgi_req;
|
||||
int i;
|
||||
time_t curtime, tdelta = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!uwsgi.async_running) return 0;
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
if (wsgi_req->async_timeout > 0) {
|
||||
if (tdelta <= 0 || tdelta > wsgi_req->async_timeout) {
|
||||
tdelta = wsgi_req->async_timeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curtime = time(NULL);
|
||||
|
||||
ret = tdelta - curtime;
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void u_green_loop() {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
|
||||
int i, current = 0, timeout;
|
||||
|
||||
for(i=0;i<uwsgi.async;i++){
|
||||
wsgi_req = uwsgi.wsgi_requests[i];
|
||||
wsgi_req->async_status = UWSGI_ACCEPTING;
|
||||
wsgi_req->async_id = i;
|
||||
}
|
||||
|
||||
uwsgi.schedule_to_main = u_green_schedule_to_main;
|
||||
uwsgi.schedule_to_req = u_green_schedule_to_req;
|
||||
|
||||
uwsgi_log("FFAR: %p\n", find_first_accepting_wsgi_req());
|
||||
|
||||
while(uwsgi.workers[uwsgi.mywid].manage_next_request) {
|
||||
|
||||
//uwsgi_log("i am uGreen...\n");
|
||||
|
||||
uwsgi.async_running = u_green_blocking();
|
||||
timeout = u_green_get_timeout();
|
||||
uwsgi.async_nevents = async_wait(uwsgi.async_queue, uwsgi.async_events, uwsgi.async, uwsgi.async_running, timeout);
|
||||
u_green_expire_timeouts();
|
||||
|
||||
if (uwsgi.async_nevents < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for(i=0; i<uwsgi.async_nevents;i++) {
|
||||
|
||||
uwsgi_log("received I/O event on fd %d\n", uwsgi.async_events[i].ASYNC_FD);
|
||||
if ( (int) uwsgi.async_events[i].ASYNC_FD == uwsgi.sockets[0].fd) {
|
||||
wsgi_req = find_first_accepting_wsgi_req();
|
||||
uwsgi_log("found wsgireq at %p\n", wsgi_req);
|
||||
if (!wsgi_req) goto cycle;
|
||||
uwsgi_log("found %d\n", wsgi_req->async_id);
|
||||
u_green_schedule_to_req(wsgi_req);
|
||||
uwsgi_log("ooops\n");
|
||||
}
|
||||
else {
|
||||
uwsgi_log("fd ready\n");
|
||||
wsgi_req = find_wsgi_req_by_fd(uwsgi.async_events[i].ASYNC_FD, -1);
|
||||
if (wsgi_req) {
|
||||
u_green_schedule_to_req(wsgi_req);
|
||||
}
|
||||
else {
|
||||
async_del(uwsgi.async_queue, uwsgi.async_events[i].ASYNC_FD, uwsgi.async_events[i].ASYNC_EV);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cycle:
|
||||
|
||||
wsgi_req = uwsgi.wsgi_requests[current];
|
||||
uwsgi_log("schedule %d %d ?\n", current, wsgi_req->async_status);
|
||||
if (wsgi_req->async_status != UWSGI_ACCEPTING && wsgi_req->async_status != UWSGI_PAUSED && wsgi_req->async_waiting_fd == -1 && !wsgi_req->async_timeout) {
|
||||
uwsgi_log("schedule !\n");
|
||||
u_green_schedule_to_req(wsgi_req);
|
||||
}
|
||||
current++;
|
||||
if (current >= uwsgi.async) current = 0;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -376,4 +141,6 @@ struct uwsgi_plugin ugreen_plugin = {
|
||||
|
||||
.name = "ugreen",
|
||||
.init = u_green_init,
|
||||
.options = ugreen_options,
|
||||
.manage_opt = uwsgi_ugreen_manage_opt,
|
||||
};
|
||||
|
||||
+180
-9
@@ -16,6 +16,112 @@ static size_t get_content_length(char *buf, uint16_t size) {
|
||||
return val;
|
||||
}
|
||||
|
||||
void set_http_date(time_t t, char *dst) {
|
||||
|
||||
static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
static char *months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr",
|
||||
"May", "Jun", "Jul", "Aug",
|
||||
"Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
struct tm *hdtm = gmtime(&t);
|
||||
snprintf(dst, 49, "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n\r\n",
|
||||
week[hdtm->tm_wday], hdtm->tm_mday,
|
||||
months[hdtm->tm_mon], hdtm->tm_year+1900,
|
||||
hdtm->tm_hour, hdtm->tm_min, hdtm->tm_sec);
|
||||
}
|
||||
|
||||
// only RFC 1123 is supported
|
||||
time_t parse_http_date(char *date, uint16_t len) {
|
||||
|
||||
struct tm hdtm;
|
||||
|
||||
if (len != 29 && date[3] != ',') return 0;
|
||||
|
||||
hdtm.tm_mday = uwsgi_str2_num(date+5);
|
||||
|
||||
switch(date[8]) {
|
||||
case 'J':
|
||||
if (date[9] == 'a') {
|
||||
hdtm.tm_mon = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (date[9] == 'u') {
|
||||
if (date[10] == 'n') {
|
||||
hdtm.tm_mon = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
if (date[10] == 'l') {
|
||||
hdtm.tm_mon = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case 'F':
|
||||
hdtm.tm_mon = 1;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (date[9] != 'a') return 0;
|
||||
|
||||
if (date[10] == 'r') {
|
||||
hdtm.tm_mon = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (date[10] == 'y') {
|
||||
hdtm.tm_mon = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case 'A':
|
||||
if (date[10] == 'r') {
|
||||
hdtm.tm_mon = 3;
|
||||
break;
|
||||
}
|
||||
if (date[10] == 'g') {
|
||||
hdtm.tm_mon = 7;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case 'S':
|
||||
hdtm.tm_mon = 8;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
hdtm.tm_mon = 9;
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
hdtm.tm_mon = 10;
|
||||
|
||||
case 'D':
|
||||
hdtm.tm_mon = 11;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdtm.tm_year = uwsgi_str4_num(date+12)-1900;
|
||||
|
||||
hdtm.tm_hour = uwsgi_str2_num(date+17);
|
||||
hdtm.tm_min = uwsgi_str2_num(date+20);
|
||||
hdtm.tm_sec = uwsgi_str2_num(date+23);
|
||||
|
||||
return timegm(&hdtm);
|
||||
|
||||
}
|
||||
|
||||
#ifdef UWSGI_UDP
|
||||
ssize_t send_udp_message(uint8_t modifier1, char *host, char *message, uint16_t message_size) {
|
||||
|
||||
@@ -346,21 +452,27 @@ int uwsgi_parse_response(struct pollfd *upoll, int timeout, struct uwsgi_header
|
||||
return 0;
|
||||
}
|
||||
|
||||
// older OSX versions make mess with CMSG_FIRSTHDR
|
||||
#ifdef __APPLE__
|
||||
if (!msg.msg_controllen) return 1;
|
||||
#endif
|
||||
|
||||
cmsg = CMSG_FIRSTHDR (&msg);
|
||||
while(cmsg != NULL) {
|
||||
if (cmsg->cmsg_len != CMSG_LEN (sizeof (int)) ||
|
||||
cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS) continue;
|
||||
if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
|
||||
cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type && SCM_RIGHTS) {
|
||||
|
||||
// upgrade connection to the new socket
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("upgrading fd %d to ", upoll->fd);
|
||||
uwsgi_log("upgrading fd %d to ", upoll->fd);
|
||||
#endif
|
||||
close(upoll->fd);
|
||||
memcpy(&upoll->fd, CMSG_DATA(cmsg), sizeof(int));
|
||||
close(upoll->fd);
|
||||
memcpy(&upoll->fd, CMSG_DATA(cmsg), sizeof(int));
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("%d\n", upoll->fd);
|
||||
uwsgi_log("%d\n", upoll->fd);
|
||||
#endif
|
||||
}
|
||||
cmsg = CMSG_NXTHDR (&msg, cmsg);
|
||||
}
|
||||
|
||||
@@ -516,6 +628,18 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->chdir = ptrbuf;
|
||||
wsgi_req->chdir_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("UWSGI_FILE", 10, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->file = ptrbuf;
|
||||
wsgi_req->file_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("UWSGI_TOUCH_RELOAD", 18, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->touch_reload = ptrbuf;
|
||||
wsgi_req->touch_reload_len = strsize;
|
||||
}
|
||||
else if (uwsgi.cache_max_items > 0 && !uwsgi_strncmp("UWSGI_CACHE_GET", 15, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->cache_get = ptrbuf;
|
||||
wsgi_req->cache_get_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("UWSGI_SETENV", 12, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
char *env_value = memchr(ptrbuf, '=', strsize);
|
||||
if (env_value) {
|
||||
@@ -545,6 +669,10 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
wsgi_req->https = ptrbuf;
|
||||
wsgi_req->https_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("HTTP_IF_MODIFIED_SINCE", 22, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->if_modified_since = ptrbuf;
|
||||
wsgi_req->if_modified_since_len = strsize;
|
||||
}
|
||||
else if (!uwsgi_strncmp("CONTENT_LENGTH", 14, wsgi_req->hvec[wsgi_req->var_cnt].iov_base, wsgi_req->hvec[wsgi_req->var_cnt].iov_len)) {
|
||||
wsgi_req->post_cl = get_content_length(ptrbuf, strsize);
|
||||
}
|
||||
@@ -570,19 +698,44 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
ptrbuf += strsize;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("Invalid uwsgi request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("Invalid uwsgi request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uwsgi_log("Invalid uwsgi request. skip.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// check if data are available in the local cache
|
||||
if (wsgi_req->cache_get_len > 0) {
|
||||
uint64_t cache_value_size;
|
||||
char *cache_value = uwsgi_cache_get(wsgi_req->cache_get, wsgi_req->cache_get_len, &cache_value_size);
|
||||
if (cache_value && cache_value_size > 0) {
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, cache_value, cache_value_size);
|
||||
wsgi_req->status = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.check_cache && wsgi_req->uri_len && wsgi_req->method_len == 3 &&
|
||||
wsgi_req->method[0] == 'G' && wsgi_req->method[1] == 'E' && wsgi_req->method[2] == 'T') {
|
||||
|
||||
uint64_t cache_value_size;
|
||||
char *cache_value = uwsgi_cache_get(wsgi_req->uri, wsgi_req->uri_len, &cache_value_size);
|
||||
if (cache_value && cache_value_size > 0) {
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, cache_value, cache_value_size);
|
||||
wsgi_req->status = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.manage_script_name) {
|
||||
if (uwsgi.apps_cnt > 0 && wsgi_req->path_info_len > 1) {
|
||||
@@ -626,6 +779,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
}
|
||||
|
||||
// check i fa file name uwsgi.check_static+env['PATH_INFO'] exists
|
||||
if (uwsgi.check_static && wsgi_req->path_info_len > 1) {
|
||||
struct stat st;
|
||||
char *filename = uwsgi_concat2n(uwsgi.check_static, uwsgi.check_static_len, wsgi_req->path_info, wsgi_req->path_info_len);
|
||||
@@ -633,13 +787,27 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
|
||||
uwsgi_log("checking for %s\n", filename);
|
||||
#endif
|
||||
if (!stat(filename, &st)) {
|
||||
if (wsgi_req->if_modified_since_len) {
|
||||
time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
|
||||
if (st.st_mtime <= ims) {
|
||||
wsgi_req->status = 304;
|
||||
wsgi_req->headers_size = write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, " 304 Not Modified\r\n\r\n", 21);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
|
||||
char http_last_modified[49];
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("file %s found\n", filename);
|
||||
#endif
|
||||
// no need to set content-type/content-length, they will be fixed by the http server/router
|
||||
wsgi_req->sendfile_fd = open(filename, O_RDONLY);
|
||||
wsgi_req->response_size = write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->response_size += write(wsgi_req->poll.fd, " 200 OK\r\n\r\n", 11);
|
||||
wsgi_req->headers_size = write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, " 200 OK\r\n", 9);
|
||||
set_http_date(st.st_mtime, http_last_modified);
|
||||
wsgi_req->headers_size += write(wsgi_req->poll.fd, http_last_modified, 48);
|
||||
wsgi_req->header_cnt = 1;
|
||||
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
|
||||
wsgi_req->status = 200;
|
||||
free(filename);
|
||||
@@ -893,6 +1061,9 @@ int uwsgi_string_sendto(int fd, uint8_t modifier1, uint8_t modifier2, struct soc
|
||||
|
||||
uh->modifier1 = modifier1;
|
||||
uh->pktsize = len;
|
||||
#ifdef __BIG_ENDIAN__
|
||||
uh->pktsize = uwsgi_swap16(uh->pktsize);
|
||||
#endif
|
||||
uh->modifier2 = modifier2;
|
||||
|
||||
memcpy(upkt+4, message, len);
|
||||
|
||||
@@ -19,6 +19,25 @@ char *uwsgi_queue_get(uint64_t index, uint64_t *size) {
|
||||
|
||||
}
|
||||
|
||||
void uwsgi_queue_fix() {
|
||||
|
||||
uint64_t i;
|
||||
char *value;
|
||||
uint64_t size;
|
||||
|
||||
for(i=0;i< uwsgi.queue_size;i++) {
|
||||
// valid record ?
|
||||
value = uwsgi_queue_get(i, &size);
|
||||
if (value && size) {
|
||||
uwsgi.shared->queue_pos++;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *uwsgi_queue_pop(uint64_t *size) {
|
||||
|
||||
struct uwsgi_queue_item *uqi;
|
||||
@@ -70,6 +89,8 @@ int uwsgi_queue_push(char *message, uint64_t size) {
|
||||
if (size > uwsgi.queue_blocksize + sizeof(struct uwsgi_queue_item))
|
||||
return 0;
|
||||
|
||||
if (!size) return 0;
|
||||
|
||||
ptr = ptr + (uwsgi.queue_blocksize*uwsgi.shared->queue_pos);
|
||||
uqi = (struct uwsgi_queue_item *) ptr;
|
||||
|
||||
|
||||
@@ -8,25 +8,38 @@ from setuptools.dist import Distribution
|
||||
from setuptools.command.install import install
|
||||
from setuptools.command.build_ext import build_ext
|
||||
|
||||
|
||||
def patch_bin_path(cmd, conf):
|
||||
|
||||
bin_name = conf.get('bin_name')
|
||||
|
||||
try:
|
||||
if not os.path.exists(cmd.install_scripts):
|
||||
os.makedirs(cmd.install_scripts)
|
||||
if not os.path.isabs(bin_name):
|
||||
print('Patching "bin_name" to properly install_scripts dir')
|
||||
conf.set('bin_name', os.path.join(cmd.install_scripts, conf.get('bin_name')))
|
||||
except:
|
||||
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
|
||||
|
||||
|
||||
class uWSGIBuilder(build_ext):
|
||||
|
||||
def run(self):
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
bin_name = conf.get('bin_name')
|
||||
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
|
||||
|
||||
class uWSGIInstall(install):
|
||||
|
||||
def run(self):
|
||||
# hack, hack and still hack. We need to find a solution for 0.9.6
|
||||
# hack, hack and still hack. We need to find a solution...
|
||||
if self.record:
|
||||
record_file = open(self.record,'w')
|
||||
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
bin_name = conf.get('bin_name')
|
||||
conf.set('bin_name', sys.prefix + '/bin/' + bin_name)
|
||||
conf = uc.uConf('buildconf/default.ini')
|
||||
patch_bin_path(self, conf)
|
||||
uc.build_uwsgi( conf )
|
||||
|
||||
class uWSGIDistribution(Distribution):
|
||||
@@ -38,7 +51,7 @@ class uWSGIDistribution(Distribution):
|
||||
|
||||
|
||||
setup(name='uWSGI',
|
||||
version='0.9.7-dev',
|
||||
version='0.9.7.1',
|
||||
description='The uWSGI server',
|
||||
author='Unbit',
|
||||
author_email='info@unbit.it',
|
||||
|
||||
@@ -91,6 +91,31 @@ int uwsgi_add_timer(uint8_t sig, int secs) {
|
||||
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t sig, int minute, int hour, int day, int month, int week) {
|
||||
|
||||
uwsgi_lock(uwsgi.cron_table_lock);
|
||||
|
||||
if (ushared->cron_cnt < MAX_CRONS) {
|
||||
|
||||
ushared->cron[ushared->cron_cnt].sig = sig;
|
||||
ushared->cron[ushared->cron_cnt].minute = minute;
|
||||
ushared->cron[ushared->cron_cnt].hour = hour;
|
||||
ushared->cron[ushared->cron_cnt].day = day;
|
||||
ushared->cron[ushared->cron_cnt].month = month;
|
||||
ushared->cron[ushared->cron_cnt].week = week;
|
||||
ushared->cron_cnt++;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("you can register max %d cron !!!\n", MAX_CRONS);
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uwsgi_unlock(uwsgi.cron_table_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_signal_add_rb_timer(uint8_t sig, int secs, int iterations) {
|
||||
|
||||
uwsgi_lock(uwsgi.rb_timer_table_lock);
|
||||
|
||||
@@ -10,20 +10,20 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
// leave 1 byte for abstract namespace (108 linux -> 104 bsd/mac)
|
||||
if (strlen(socket_name) > 102) {
|
||||
uwsgi_log( "invalid socket name\n");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
uws_addr = malloc(sizeof(struct sockaddr_un));
|
||||
if (uws_addr == NULL) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
memset(uws_addr, 0, sizeof(struct sockaddr_un));
|
||||
serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
if (abstract_socket == 0) {
|
||||
if (unlink(socket_name) != 0 && errno != ENOENT) {
|
||||
@@ -44,13 +44,13 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
if (bind(serverfd, (struct sockaddr *) uws_addr, strlen(socket_name) + abstract_socket + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
|
||||
#endif
|
||||
uwsgi_error("bind()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
// chmod unix socket for lazy users
|
||||
@@ -104,7 +104,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
uwsgi_log( "binding on %d SCTP interfaces on port: %d\n", num_ip, ntohs(uws_addr[0].sin_port));
|
||||
@@ -112,7 +112,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
|
||||
if (sctp_bindx(serverfd, (struct sockaddr *) uws_addr, num_ip, SCTP_BINDX_ADD_ADDR) != 0) {
|
||||
uwsgi_error("sctp_bindx()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
sctp_im.sinit_max_instreams = 0xFFFF;
|
||||
@@ -124,7 +124,7 @@ int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abst
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
return serverfd;
|
||||
@@ -328,7 +328,7 @@ char *generate_socket_name(char *socket_name) {
|
||||
struct ifaddrs *ifap = NULL, *ifa, *ifaf;
|
||||
if (getifaddrs(&ifap)) {
|
||||
uwsgi_error("getifaddrs()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
// here socket_name will be truncated
|
||||
@@ -359,7 +359,7 @@ char *generate_socket_name(char *socket_name) {
|
||||
}
|
||||
|
||||
uwsgi_log("unable to find avalid socket address\n");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
return socket_name ;
|
||||
}
|
||||
@@ -381,7 +381,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
serverfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (serverfd < 0) {
|
||||
uwsgi_error("socket()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (socket_name[0] == 0) {
|
||||
@@ -394,7 +394,7 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
|
||||
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
|
||||
uwsgi_error("setsockopt()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (!uwsgi.no_defer_accept) {
|
||||
@@ -421,12 +421,12 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
|
||||
uwsgi_log("probably another instance of uWSGI is running on the same address.\n");
|
||||
}
|
||||
uwsgi_error("bind()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
if (listen(serverfd, listen_queue) != 0) {
|
||||
uwsgi_error("listen()");
|
||||
exit(1);
|
||||
uwsgi_nuclear_blast();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size) {
|
||||
|
||||
fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(filename);
|
||||
uwsgi_unlock(uwsgi.spooler_lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ void spooler() {
|
||||
|
||||
nullfd = open("/dev/null", O_RDONLY);
|
||||
if (nullfd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ void spooler() {
|
||||
|
||||
spool_fd = open(dp->d_name, O_RDONLY);
|
||||
if (spool_fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(dp->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
#ifdef UWSGI_STACKLESS
|
||||
|
||||
#include "uwsgi.h"
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct wsgi_request* find_request_by_tasklet(PyTaskletObject *tasklet) {
|
||||
|
||||
int i;
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
if (uwsgi.stackless_table[i]->tasklet == tasklet) {
|
||||
return uwsgi.stackless_table[i]->wsgi_req;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *py_uwsgi_stackless_worker(PyObject * self, PyObject * args) {
|
||||
|
||||
PyThreadState *ts = PyThreadState_GET();
|
||||
struct wsgi_request *wsgi_req = find_request_by_tasklet(ts->st.current);
|
||||
PyObject *zero;
|
||||
|
||||
int async_id = wsgi_req->async_id;
|
||||
|
||||
//uwsgi_log("i am the tasklet worker\n");
|
||||
|
||||
for(;;) {
|
||||
|
||||
// wait for request
|
||||
zero = PyChannel_Receive(uwsgi.workers_channel);
|
||||
|
||||
wsgi_req_setup(wsgi_req, async_id);
|
||||
|
||||
if (wsgi_req_accept(uwsgi.serverfd, wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wsgi_req_recv(wsgi_req)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uwsgi_close_request(&uwsgi, wsgi_req);
|
||||
}
|
||||
}
|
||||
|
||||
PyMethodDef uwsgi_stackless_worker[] = { {"uwsgi_stackless_worker", py_uwsgi_stackless_worker, METH_VARARGS, ""} };
|
||||
|
||||
void stackless_init(struct uwsgi_server *uwsgi) {
|
||||
int i;
|
||||
struct wsgi_request* wsgi_req = uwsgi->wsgi_requests;
|
||||
|
||||
PyObject *tasklet_worker = PyCFunction_New(uwsgi_stackless_worker, NULL);
|
||||
|
||||
uwsgi->workers_channel = PyChannel_New(NULL);
|
||||
|
||||
uwsgi->stackless_table = malloc( sizeof(struct stackless_req*) * uwsgi->async);
|
||||
if (!uwsgi->stackless_table) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
for(i=0;i<uwsgi->async;i++) {
|
||||
uwsgi->stackless_table[i] = malloc(sizeof(struct stackless_req));
|
||||
if (!uwsgi->stackless_table[i]) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
}
|
||||
memset(uwsgi->stackless_table[i], 0, sizeof(struct stackless_req));
|
||||
}
|
||||
|
||||
uwsgi_log("initializing %d tasklet...", uwsgi->async);
|
||||
|
||||
// creating uwsgi->async tasklets
|
||||
for(i=0;i<uwsgi->async;i++) {
|
||||
wsgi_req->tasklet = PyTasklet_New(NULL, tasklet_worker);
|
||||
uwsgi->stackless_table[i]->tasklet = wsgi_req->tasklet;
|
||||
uwsgi->stackless_table[i]->wsgi_req = wsgi_req;
|
||||
// useless for now, it will be used for I/O or other messaging
|
||||
uwsgi->stackless_table[i]->channel = NULL;
|
||||
wsgi_req->async_id = i;
|
||||
|
||||
PyTasklet_Setup(wsgi_req->tasklet, PyTuple_New(0), NULL);
|
||||
//PyTasklet_Run(wsgi_req->tasklet);
|
||||
wsgi_req = next_wsgi_req(uwsgi, wsgi_req);
|
||||
}
|
||||
|
||||
uwsgi_log("done\n");
|
||||
}
|
||||
|
||||
void stackless_loop(struct uwsgi_server *uwsgi) {
|
||||
|
||||
int i;
|
||||
PyTaskletObject *int_tasklet;
|
||||
|
||||
// tasklets main loop
|
||||
for(;;) {
|
||||
//uwsgi->async_running = -1;
|
||||
//if (PyStackless_GetRunCount() > 0) {
|
||||
uwsgi->async_running = 0;
|
||||
//}
|
||||
uwsgi->async_nevents = async_wait(uwsgi->async_queue, uwsgi->async_events, uwsgi->async, uwsgi->async_running, 0);
|
||||
|
||||
if (uwsgi->async_nevents < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i=0; i<uwsgi->async_nevents;i++) {
|
||||
|
||||
if (uwsgi->async_events[i].ASYNC_FD == uwsgi->serverfd) {
|
||||
//pass the connection to the first available tasklet
|
||||
uwsgi_log("sending new connection...\n");
|
||||
PyChannel_Send(uwsgi->workers_channel, Py_True);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
if (PyStackless_GetRunCount() > 0) {
|
||||
PyStackless_Schedule(Py_None, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
PyStackless_RunWatchdogEx( 10, PY_WATCHDOG_TOTALTIMEOUT);
|
||||
|
||||
//int_tasklet = (PyTaskletObject *) PyStackless_RunWatchdog( 1000 );
|
||||
/*
|
||||
uwsgi_log("done watchdog %p\n", int_tasklet);
|
||||
if (!PyTasklet_IsCurrent(int_tasklet)) {
|
||||
uwsgi_log("re-insert: %d\n", 1);// PyTasklet_Insert(int_tasklet));
|
||||
}
|
||||
uwsgi_log("recycle\n");
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
def application(env, start_response):
|
||||
while 1:
|
||||
pass
|
||||
+25
-29
@@ -1,47 +1,43 @@
|
||||
import socket
|
||||
import select
|
||||
import errno
|
||||
import uwsgi
|
||||
|
||||
def send_request(env, client):
|
||||
|
||||
client.setblocking(1)
|
||||
uwsgi.send(client, b"GET /intl/it_it/images/logo.gif HTTP/1.0\r\n")
|
||||
|
||||
# test for suspend/resume
|
||||
uwsgi.suspend()
|
||||
|
||||
uwsgi.send(client, b"Host: www.google.it\r\n\r\n")
|
||||
|
||||
client.send(b"GET /intl/it_it/images/logo.gif HTTP/1.0\r\n")
|
||||
client.send(b"Host: www.google.it\r\n\r\n")
|
||||
|
||||
while 1:
|
||||
yield env['x-wsgiorg.fdevent.readable'](client.fileno(), 10)
|
||||
buf = client.recv(4096)
|
||||
if len(buf) == 0:
|
||||
break
|
||||
else:
|
||||
yield uwsgi.wait_fd_read(client, 2)
|
||||
if env['x-wsgiorg.fdevent.timeout']:
|
||||
return
|
||||
|
||||
buf = uwsgi.recv(client, 4096)
|
||||
if buf:
|
||||
yield buf
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
def application(env, start_response):
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.setblocking(0)
|
||||
c = uwsgi.async_connect('74.125.232.115:80')
|
||||
|
||||
#env['x-wsgiorg.fdevent.readable'] = lambda fd,t: ""
|
||||
#env['x-wsgiorg.fdevent.writable'] = lambda fd,t: ""
|
||||
# wait for connection
|
||||
yield uwsgi.wait_fd_write(c, 2)
|
||||
|
||||
if env['x-wsgiorg.fdevent.timeout']:
|
||||
uwsgi.close(c)
|
||||
raise StopIteration
|
||||
|
||||
#yield ""
|
||||
|
||||
print "opening socket"
|
||||
|
||||
c = s.connect_ex(('www.google.it', 80))
|
||||
if c == errno.EINPROGRESS:
|
||||
print "yielding"
|
||||
yield env['x-wsgiorg.fdevent.writable'](s.fileno(), 10)
|
||||
print "waiting for fd write"
|
||||
for r in send_request(env, s):
|
||||
yield r
|
||||
elif c == errno.EISCONN:
|
||||
for r in send_request(env, s):
|
||||
if uwsgi.is_connected(c):
|
||||
for r in send_request(env, c):
|
||||
yield r
|
||||
else:
|
||||
start_response( '500 Internal Server Error', [ ('Content-Type', 'text/html')])
|
||||
yield "Internal Server Error"
|
||||
|
||||
s.close()
|
||||
uwsgi.close(c)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import sys
|
||||
import uwsgi
|
||||
|
||||
content_type = 'image/png'
|
||||
filename = 'logo_uWSGI.png'
|
||||
|
||||
@@ -70,6 +70,12 @@ void daemonize(char *logfile) {
|
||||
pid_t pid;
|
||||
int fdin;
|
||||
|
||||
// do not daemonize under emperor
|
||||
if (uwsgi.has_emperor) {
|
||||
logto(logfile);
|
||||
return;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
uwsgi_error("fork()");
|
||||
@@ -104,7 +110,7 @@ void daemonize(char *logfile) {
|
||||
|
||||
fdin = open("/dev/null", O_RDWR);
|
||||
if (fdin < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -155,7 +161,7 @@ void logto(char *logfile) {
|
||||
#endif
|
||||
fd = open(logfile, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(logfile);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef UWSGI_UDP
|
||||
@@ -269,7 +275,7 @@ void uwsgi_as_root() {
|
||||
cgroup_taskfile = uwsgi_concat2(uwsgi.cgroup, "/tasks");
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (!cgroup) {
|
||||
uwsgi_error("fopen");
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(cgroup, "%d\n", (int) getpid()) < 0) {
|
||||
@@ -295,7 +301,7 @@ void uwsgi_as_root() {
|
||||
cgroup_taskfile = uwsgi_concat3(uwsgi.cgroup, "/", uwsgi.cgroup_opt[i]);
|
||||
cgroup = fopen(cgroup_taskfile, "w");
|
||||
if (!cgroup) {
|
||||
uwsgi_error("fopen");
|
||||
uwsgi_error_open(cgroup_taskfile);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(cgroup, "%s\n", cgroup_opt) < 0) {
|
||||
@@ -338,6 +344,13 @@ void uwsgi_as_root() {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.logfile_chown) {
|
||||
if (fchown(2, uwsgi.uid, uwsgi.gid)) {
|
||||
uwsgi_error("fchown()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (uwsgi.gid) {
|
||||
if (!uwsgi.master_as_root) uwsgi_log("setgid() to %d\n", uwsgi.gid);
|
||||
if (setgid(uwsgi.gid)) {
|
||||
@@ -376,6 +389,7 @@ void uwsgi_as_root() {
|
||||
void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
int waitpid_status;
|
||||
int tmp_id;
|
||||
|
||||
gettimeofday(&wsgi_req->end_of_request, NULL);
|
||||
uwsgi.workers[uwsgi.mywid].running_time += (double) (((double) (wsgi_req->end_of_request.tv_sec * 1000000 + wsgi_req->end_of_request.tv_usec) - (double) (wsgi_req->start_of_request.tv_sec * 1000000 + wsgi_req->start_of_request.tv_usec)) / (double) 1000.0);
|
||||
@@ -394,10 +408,6 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
uwsgi.workers[0].requests++;
|
||||
uwsgi.workers[uwsgi.mywid].requests++;
|
||||
|
||||
if (uwsgi.cores > 1) {
|
||||
uwsgi.core[wsgi_req->async_id]->requests++;
|
||||
}
|
||||
|
||||
// after_request hook
|
||||
if (uwsgi.p[wsgi_req->uh.modifier1]->after_request) uwsgi.p[wsgi_req->uh.modifier1]->after_request(wsgi_req);
|
||||
|
||||
@@ -412,7 +422,9 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
|
||||
}
|
||||
|
||||
// reset request
|
||||
tmp_id = wsgi_req->async_id;
|
||||
memset(wsgi_req, 0, sizeof(struct wsgi_request));
|
||||
wsgi_req->async_id = tmp_id;
|
||||
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_MAX_REQUESTS] > 0 && uwsgi.workers[uwsgi.mywid].requests >= uwsgi.shared->options[UWSGI_OPTION_MAX_REQUESTS]) {
|
||||
goodbye_cruel_world();
|
||||
@@ -430,9 +442,6 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id) {
|
||||
wsgi_req->sendfile_fd = -1;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
wsgi_req->async_waiting_fd = -1;
|
||||
#endif
|
||||
wsgi_req->hvec = uwsgi.async_hvec[wsgi_req->async_id];
|
||||
wsgi_req->buffer = uwsgi.async_buf[wsgi_req->async_id];
|
||||
|
||||
@@ -447,6 +456,25 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id) {
|
||||
|
||||
}
|
||||
|
||||
int wsgi_req_simple_recv(struct wsgi_request *wsgi_req) {
|
||||
|
||||
UWSGI_SET_IN_REQUEST;
|
||||
|
||||
gettimeofday(&wsgi_req->start_of_request, NULL);
|
||||
|
||||
|
||||
if (!uwsgi_parse_response(&wsgi_req->poll, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], (struct uwsgi_header *) wsgi_req, wsgi_req->buffer)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// enter harakiri mode
|
||||
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
||||
set_harakiri(uwsgi.shared->options[UWSGI_OPTION_HARAKIRI]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wsgi_req_recv(struct wsgi_request *wsgi_req) {
|
||||
|
||||
UWSGI_SET_IN_REQUEST;
|
||||
@@ -504,7 +532,7 @@ polling:
|
||||
if (read(uwsgi.sockets_poll[uwsgi.sockets_cnt].fd, &uwsgi_signal, 1) <= 0) {
|
||||
if (uwsgi.no_orphans) {
|
||||
uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid);
|
||||
end_me();
|
||||
end_me(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -551,21 +579,6 @@ polling:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UWSGI_STACKLESS
|
||||
inline struct wsgi_request *current_wsgi_req() {
|
||||
|
||||
struct wsgi_request *wsgi_req = uwsgi.wsgi_req;
|
||||
|
||||
if (uwsgi.stackless && uwsgi.async >1) {
|
||||
PyThreadState *ts = PyThreadState_GET();
|
||||
wsgi_req = find_request_by_tasklet(ts->st.current);
|
||||
}
|
||||
|
||||
return wsgi_req;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void sanitize_args() {
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
@@ -614,13 +627,11 @@ void env_to_arg(char *src, char *dst) {
|
||||
|
||||
void parse_sys_envs(char **envs) {
|
||||
|
||||
struct option *lopt, *aopt;
|
||||
|
||||
char **uenvs = envs;
|
||||
char *earg, *eq_pos;
|
||||
|
||||
while(*uenvs) {
|
||||
if (!strncmp(*uenvs, "UWSGI_", 6)) {
|
||||
if (!strncmp(*uenvs, "UWSGI_", 6) && strncmp(*uenvs, "UWSGI_RELOADS=",14)) {
|
||||
earg = uwsgi_malloc(strlen(*uenvs+6)+1);
|
||||
env_to_arg(*uenvs+6, earg);
|
||||
eq_pos = strchr(earg, '=');
|
||||
@@ -629,27 +640,7 @@ void parse_sys_envs(char **envs) {
|
||||
}
|
||||
eq_pos[0] = 0;
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(earg, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
}
|
||||
else {
|
||||
if (eq_pos[1] != 0) {
|
||||
manage_opt(aopt->val, eq_pos+1);
|
||||
}
|
||||
else {
|
||||
manage_opt(aopt->val, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
add_exported_option(earg, eq_pos+1, 0);
|
||||
}
|
||||
uenvs++;
|
||||
}
|
||||
@@ -963,6 +954,7 @@ char *uwsgi_strncopy(char *s, int len) {
|
||||
int uwsgi_get_app_id(char *script_name, int script_name_len, int modifier1) {
|
||||
|
||||
int i;
|
||||
struct stat st;
|
||||
|
||||
for(i=0;i<uwsgi.apps_cnt;i++) {
|
||||
//uwsgi_log("searching for %.*s in %.*s %p\n", script_name_len, script_name, uwsgi.apps[i].mountpoint_len, uwsgi.apps[i].mountpoint, uwsgi.apps[i].callable);
|
||||
@@ -970,6 +962,15 @@ int uwsgi_get_app_id(char *script_name, int script_name_len, int modifier1) {
|
||||
continue;
|
||||
}
|
||||
if (!uwsgi_strncmp(uwsgi.apps[i].mountpoint, uwsgi.apps[i].mountpoint_len, script_name, script_name_len)) {
|
||||
if (uwsgi.apps[i].touch_reload) {
|
||||
if (!stat(uwsgi.apps[i].touch_reload, &st)) {
|
||||
if (st.st_mtime != uwsgi.apps[i].touch_reload_mtime) {
|
||||
// serve the new request and reload
|
||||
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (modifier1 == -1) return i;
|
||||
if (modifier1 == uwsgi.apps[i].modifier1) return i;
|
||||
}
|
||||
@@ -1084,7 +1085,7 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
|
||||
// here we use O_EXCL to avoid eventual application bug in uuid generation/using
|
||||
upload_progress_fd = open(upload_progress_filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
if (upload_progress_fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(upload_progress_filename);
|
||||
free(upload_progress_filename);
|
||||
}
|
||||
}
|
||||
@@ -1173,37 +1174,7 @@ end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_exported_option(int i, char *value) {
|
||||
|
||||
char *key = NULL;
|
||||
struct option *lopt, *aopt;
|
||||
|
||||
if (i == 0) {
|
||||
key = value;
|
||||
value = NULL;
|
||||
}
|
||||
else {
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (aopt->val == 0 && *aopt->flag == i) {
|
||||
key = (char *) aopt->name;
|
||||
break;
|
||||
}
|
||||
if (aopt->val == i) {
|
||||
key = (char *) aopt->name;
|
||||
break;
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
}
|
||||
|
||||
//uwsgi_log("%s = %s\n", key, value);
|
||||
|
||||
if (!key) return;
|
||||
|
||||
|
||||
void add_exported_option(char *key, char *value, int configured) {
|
||||
|
||||
if (!uwsgi.exported_opts) {
|
||||
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt*));
|
||||
@@ -1216,10 +1187,10 @@ void add_exported_option(int i, char *value) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
|
||||
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
|
||||
uwsgi.exported_opts_cnt++;
|
||||
|
||||
}
|
||||
@@ -1401,7 +1372,7 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
if (add_zero) {
|
||||
*size = *size + 1;
|
||||
buffer = realloc(buffer, *size);
|
||||
buffer[*size] = 0;
|
||||
buffer[*size-1] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1409,7 +1380,7 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
else {
|
||||
fd = open(url, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(url);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -1489,6 +1460,7 @@ void init_magic_table(char *magic_table[]) {
|
||||
}
|
||||
|
||||
magic_table['%'] = "%";
|
||||
magic_table['('] = "%(";
|
||||
}
|
||||
|
||||
char *uwsgi_get_last_char(char *what, char c) {
|
||||
@@ -1634,8 +1606,120 @@ int is_a_number(char *what) {
|
||||
int i;
|
||||
|
||||
for(i=0;i<(int)strlen(what);i++) {
|
||||
if (!isdigit(what[i])) return 0;
|
||||
if (!isdigit((int)what[i])) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uwsgi_unix_signal(int signum, void (*func)(int)) {
|
||||
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof(struct sigaction));
|
||||
|
||||
sa.sa_handler = func;
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
||||
if (sigaction(signum, &sa, NULL) < 0) {
|
||||
uwsgi_error("sigaction()");
|
||||
}
|
||||
}
|
||||
|
||||
char *uwsgi_get_exported_opt(char *key) {
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
|
||||
if (!strcmp(uwsgi.exported_opts[i]->key, key)) {
|
||||
return uwsgi.exported_opts[i]->value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *uwsgi_get_optname_by_index(int index) {
|
||||
|
||||
struct option *aopt;
|
||||
struct option *lopt = uwsgi.long_options;
|
||||
|
||||
while ( (aopt = lopt) ) {
|
||||
if (!aopt->name) break;
|
||||
if (aopt->val == index) {
|
||||
return (char *) aopt->name;
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uwsgi_list_has_num(char *list, int num) {
|
||||
|
||||
char *list2 = uwsgi_concat2(list, "");
|
||||
|
||||
char *p = strtok(list2, ",");
|
||||
while (p != NULL) {
|
||||
if (atoi(p) == num) {
|
||||
free(list2);
|
||||
return 1;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_list_has_str(char *list, char *str) {
|
||||
|
||||
char *list2 = uwsgi_concat2(list+1, "");
|
||||
|
||||
char *p = strtok(list2, " ");
|
||||
while (p != NULL) {
|
||||
if (!strcasecmp(p, str)) {
|
||||
free(list2);
|
||||
return 1;
|
||||
}
|
||||
p = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
free(list2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uwsgi_str2_num(char *str) {
|
||||
|
||||
int num = 0;
|
||||
|
||||
num = 10 * (str[0] - 48);
|
||||
num += str[1] - 48;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int uwsgi_str3_num(char *str) {
|
||||
|
||||
int num = 0;
|
||||
|
||||
num = 100 * (str[0] - 48);
|
||||
num += 10 * (str[1] - 48);
|
||||
num += str[2] - 48;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_str4_num(char *str) {
|
||||
|
||||
int num = 0;
|
||||
|
||||
num = 1000 * (str[0] - 48);
|
||||
num += 100 * (str[1] - 48);
|
||||
num += 10 * (str[2] - 48);
|
||||
num += str[3] - 48;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
/* indent -i8 -br -brs -brf -l0 -npsl -nip -npcs -npsl -di1 */
|
||||
|
||||
#define UWSGI_VERSION "0.9.7-dev"
|
||||
#define UWSGI_VERSION "0.9.7.1"
|
||||
|
||||
#define UMAX16 65536
|
||||
|
||||
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_error_open(x) uwsgi_log("open(\"%s\"): %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
|
||||
#define uwsgi_debug(x, ...) uwsgi_log("[uWSGI DEBUG] " x, __VA_ARGS__);
|
||||
#define uwsgi_rawlog(x) if (write(2, x, strlen(x)) != strlen(x)) uwsgi_error("write()")
|
||||
|
||||
@@ -14,12 +15,14 @@
|
||||
|
||||
#define ushared uwsgi.shared
|
||||
|
||||
#define MAX_SOCKETS 8
|
||||
#define MAX_APPS 64
|
||||
#define MAX_GENERIC_PLUGINS 64
|
||||
#define MAX_RPC 64
|
||||
#define MAX_GATEWAYS 64
|
||||
#define MAX_DAEMONS 8
|
||||
#define MAX_SUBSCRIPTIONS 8
|
||||
#define MAX_CRONS 64
|
||||
|
||||
#ifndef UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
#define UWSGI_LOAD_EMBEDDED_PLUGINS
|
||||
@@ -97,6 +100,10 @@
|
||||
|
||||
|
||||
#ifdef __linux
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
#include <sched.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <sys/mount.h>
|
||||
@@ -203,6 +210,13 @@ extern int pivot_root(const char * new_root, const char * put_old);
|
||||
|
||||
#define uwsgi_cache_update_start(x, y, z) uwsgi_cache_set(x, y, "", 0, CACHE_FLAG_UNGETTABLE)
|
||||
|
||||
struct uwsgi_help_item {
|
||||
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
|
||||
union uwsgi_sockaddr {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sa_in;
|
||||
@@ -273,6 +287,7 @@ struct uwsgi_cache_item {
|
||||
struct uwsgi_opt {
|
||||
char *key;
|
||||
char *value;
|
||||
int configured;
|
||||
};
|
||||
|
||||
#define MAX_CLUSTER_NODES 100
|
||||
@@ -355,7 +370,15 @@ struct uwsgi_opt {
|
||||
#define LONG_ARGS_SUBSCRIBE_TO 17078
|
||||
#define LONG_ARGS_CLUSTER_NODES 17079
|
||||
#define LONG_ARGS_RELOAD_MERCY 17080
|
||||
|
||||
#define LONG_ARGS_ALLOWED_MODIFIERS 17081
|
||||
#define LONG_ARGS_LINUX_NS_NET 17082
|
||||
#define LONG_ARGS_CPU_AFFINITY 17083
|
||||
#define LONG_ARGS_CACHE_STORE 17084
|
||||
#define LONG_ARGS_CACHE_STORE_SYNC 17085
|
||||
#define LONG_ARGS_QUEUE_STORE 17086
|
||||
#define LONG_ARGS_QUEUE_STORE_SYNC 17087
|
||||
#define LONG_ARGS_PIDFILE2 17088
|
||||
#define LONG_ARGS_MAP_SOCKET 17089
|
||||
|
||||
|
||||
#define UWSGI_OK 0
|
||||
@@ -483,6 +506,8 @@ struct uwsgi_plugin {
|
||||
|
||||
uint16_t (*rpc)(void *, uint8_t, char **, char *);
|
||||
|
||||
struct uwsgi_help_item *help;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -519,6 +544,9 @@ struct uwsgi_app {
|
||||
int requests;
|
||||
char *chdir;
|
||||
|
||||
char *touch_reload;
|
||||
time_t touch_reload_mtime;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -552,6 +580,13 @@ struct __attribute__ ((packed)) uwsgi_header {
|
||||
uint8_t modifier2;
|
||||
};
|
||||
|
||||
struct uwsgi_async_fd {
|
||||
int fd;
|
||||
int event;
|
||||
struct uwsgi_async_fd* prev;
|
||||
struct uwsgi_async_fd* next;
|
||||
};
|
||||
|
||||
|
||||
struct wsgi_request {
|
||||
struct uwsgi_header uh;
|
||||
@@ -614,6 +649,15 @@ struct wsgi_request {
|
||||
char *chdir;
|
||||
uint16_t chdir_len;
|
||||
|
||||
char *touch_reload;
|
||||
uint16_t touch_reload_len;
|
||||
|
||||
char *cache_get;
|
||||
uint16_t cache_get_len;
|
||||
|
||||
char *if_modified_since;
|
||||
uint16_t if_modified_since_len;
|
||||
|
||||
int fd_closed;
|
||||
|
||||
int sendfile_fd;
|
||||
@@ -631,14 +675,14 @@ struct wsgi_request {
|
||||
|
||||
int async_id;
|
||||
int async_status;
|
||||
int async_waiting_fd;
|
||||
int async_waiting_fd_type;
|
||||
int async_waiting_fd_monitored;
|
||||
|
||||
int switches;
|
||||
|
||||
time_t async_timeout;
|
||||
int async_timeout_expired;
|
||||
int async_timed_out;
|
||||
int async_ready_fd;
|
||||
int async_last_ready_fd;
|
||||
struct uwsgi_rb_timer *async_timeout;
|
||||
struct uwsgi_async_fd *waiting_fds;
|
||||
|
||||
void *async_app;
|
||||
void *async_result;
|
||||
@@ -650,6 +694,8 @@ struct wsgi_request {
|
||||
|
||||
int async_plagued;
|
||||
|
||||
int suspended;
|
||||
|
||||
int *ovector;
|
||||
size_t post_cl;
|
||||
char *post_buffering_buf;
|
||||
@@ -715,12 +761,15 @@ struct uwsgi_server {
|
||||
|
||||
time_t master_mercy;
|
||||
|
||||
int cpu_affinity;
|
||||
|
||||
int reload_mercy;
|
||||
int option_index;
|
||||
struct option *long_options;
|
||||
struct uwsgi_opt **exported_opts;
|
||||
int exported_opts_cnt;
|
||||
int dump_options;
|
||||
int show_config;
|
||||
//base for all the requests(even on async mode)
|
||||
struct wsgi_request **wsgi_requests;
|
||||
struct wsgi_request *wsgi_req;
|
||||
@@ -753,6 +802,7 @@ struct uwsgi_server {
|
||||
size_t check_static_len;
|
||||
|
||||
char *logfile;
|
||||
int logfile_chown;
|
||||
|
||||
int vhost;
|
||||
int vhost_host;
|
||||
@@ -761,8 +811,16 @@ struct uwsgi_server {
|
||||
char **async_buf;
|
||||
char **async_post_buf;
|
||||
|
||||
int *async_waiting_fd_table;
|
||||
int async_current_max;
|
||||
struct wsgi_request **async_waiting_fd_table;
|
||||
struct uwsgi_async_request *async_runqueue;
|
||||
struct uwsgi_async_request *async_runqueue_last;
|
||||
int async_runqueue_cnt;
|
||||
|
||||
struct rb_root *rb_async_timeouts;
|
||||
|
||||
int async_queue_unused_ptr;
|
||||
struct wsgi_request **async_queue_unused;
|
||||
|
||||
|
||||
#ifdef UWSGI_ROUTING
|
||||
int **async_ovector;
|
||||
@@ -791,13 +849,10 @@ struct uwsgi_server {
|
||||
char *spool_dir;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_NAGIOS
|
||||
int nagios;
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
int snmp;
|
||||
char *snmp_community;
|
||||
char *snmp_addr;
|
||||
char *snmp_community;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -818,6 +873,7 @@ struct uwsgi_server {
|
||||
int page_size;
|
||||
|
||||
char *pidfile;
|
||||
char *pidfile2;
|
||||
|
||||
int harakiri_verbose;
|
||||
|
||||
@@ -827,14 +883,6 @@ struct uwsgi_server {
|
||||
int async_queue;
|
||||
int async_nevents;
|
||||
|
||||
#ifdef __linux__
|
||||
struct epoll_event *async_events;
|
||||
#elif defined(__sun__)
|
||||
struct pollfd *async_events;
|
||||
#else
|
||||
struct kevent *async_events;
|
||||
#endif
|
||||
|
||||
int max_vars;
|
||||
int vec_size;
|
||||
|
||||
@@ -914,13 +962,16 @@ struct uwsgi_server {
|
||||
char *cgroup_opt[64];
|
||||
int cgroup_opt_cnt;
|
||||
char *ns;
|
||||
char *ns_net;
|
||||
#endif
|
||||
|
||||
int sockets_cnt;
|
||||
struct uwsgi_socket sockets[8];
|
||||
struct uwsgi_socket sockets[MAX_SOCKETS];
|
||||
// leave a slot for no-orphan mode
|
||||
struct pollfd sockets_poll[9];
|
||||
|
||||
char *map_socket[MAX_SOCKETS];
|
||||
|
||||
time_t respawn_delta;
|
||||
|
||||
char *mounts[MAX_APPS];
|
||||
@@ -940,6 +991,7 @@ struct uwsgi_server {
|
||||
|
||||
// usedby suspend/resume loops
|
||||
void (*schedule_to_main) (struct wsgi_request *);
|
||||
void (*schedule_to_req) (void);
|
||||
|
||||
int close_on_exec;
|
||||
|
||||
@@ -950,6 +1002,8 @@ struct uwsgi_server {
|
||||
struct uwsgi_plugin *p[0xFF];
|
||||
struct uwsgi_plugin *gp[MAX_GENERIC_PLUGINS];
|
||||
int gp_cnt;
|
||||
|
||||
char *allowed_modifiers;
|
||||
|
||||
char *upload_progress;
|
||||
|
||||
@@ -957,6 +1011,8 @@ struct uwsgi_server {
|
||||
int cluster_nodes;
|
||||
int cluster_fd;
|
||||
struct sockaddr_in mc_cluster_addr;
|
||||
|
||||
int check_cache;
|
||||
|
||||
uint32_t cache_max_items;
|
||||
uint64_t *cache_hashtable;
|
||||
@@ -964,10 +1020,16 @@ struct uwsgi_server {
|
||||
uint64_t cache_blocksize;
|
||||
struct uwsgi_cache_item *cache_items;
|
||||
void *cache;
|
||||
char *cache_store;
|
||||
size_t cache_filesize;
|
||||
int cache_store_sync;
|
||||
|
||||
uint64_t queue_size;
|
||||
uint64_t queue_blocksize;
|
||||
void *queue;
|
||||
char *queue_store;
|
||||
size_t queue_filesize;
|
||||
int queue_store_sync;
|
||||
|
||||
void *cache_lock;
|
||||
void *queue_lock;
|
||||
@@ -976,6 +1038,7 @@ struct uwsgi_server {
|
||||
void *fmon_table_lock;
|
||||
void *timer_table_lock;
|
||||
void *rb_timer_table_lock;
|
||||
void *cron_table_lock;
|
||||
void *rpc_table_lock;
|
||||
void *spooler_lock;
|
||||
|
||||
@@ -1061,6 +1124,18 @@ struct uwsgi_snmp_server_value {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct uwsgi_cron {
|
||||
|
||||
int minute;
|
||||
int hour;
|
||||
int day;
|
||||
int month;
|
||||
int week;
|
||||
|
||||
time_t last_job;
|
||||
uint8_t sig;
|
||||
};
|
||||
|
||||
struct uwsgi_shared {
|
||||
|
||||
//vga 80 x25 specific !
|
||||
@@ -1116,6 +1191,9 @@ struct uwsgi_shared {
|
||||
#ifdef __linux__
|
||||
struct tcp_info ti;
|
||||
#endif
|
||||
|
||||
struct uwsgi_cron cron[MAX_CRONS];
|
||||
int cron_cnt;
|
||||
};
|
||||
|
||||
struct uwsgi_core {
|
||||
@@ -1125,7 +1203,7 @@ struct uwsgi_core {
|
||||
|
||||
time_t harakiri;
|
||||
|
||||
uint64_t requests;
|
||||
//uint64_t requests;
|
||||
uint64_t failed_requests;
|
||||
|
||||
//multiple ts per - core are needed only with multiple_interpreter + threads
|
||||
@@ -1156,6 +1234,8 @@ struct uwsgi_worker {
|
||||
|
||||
uint64_t exceptions;
|
||||
|
||||
char sockets_mask[MAX_SOCKETS];
|
||||
|
||||
};
|
||||
|
||||
char *uwsgi_get_cwd(void);
|
||||
@@ -1163,12 +1243,12 @@ char *uwsgi_get_cwd(void);
|
||||
void warn_pipe(void);
|
||||
void what_i_am_doing(void);
|
||||
void goodbye_cruel_world(void);
|
||||
void gracefully_kill(void);
|
||||
void reap_them_all(void);
|
||||
void kill_them_all(void);
|
||||
void grace_them_all(void);
|
||||
void reload_me(void);
|
||||
void end_me(void);
|
||||
void gracefully_kill(int);
|
||||
void reap_them_all(int);
|
||||
void kill_them_all(int);
|
||||
void grace_them_all(int);
|
||||
void reload_me(int);
|
||||
void end_me(int);
|
||||
int bind_to_unix(char *, int, int, int);
|
||||
int bind_to_tcp(char *, int, char *);
|
||||
int bind_to_udp(char *, int, int);
|
||||
@@ -1188,7 +1268,7 @@ void log_request(struct wsgi_request *);
|
||||
void get_memusage(void);
|
||||
void harakiri(void);
|
||||
|
||||
void stats(void);
|
||||
void stats(int);
|
||||
|
||||
#ifdef UWSGI_XML
|
||||
void uwsgi_xml_config(struct wsgi_request *, int, char *[]);
|
||||
@@ -1239,14 +1319,15 @@ struct http_status_codes {
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
|
||||
#define ASYNC_IN 1
|
||||
#define ASYNC_OUT 2
|
||||
struct wsgi_request *async_loop(void);
|
||||
void *async_loop(void *);
|
||||
struct wsgi_request *find_first_available_wsgi_req(void);
|
||||
struct wsgi_request *find_first_accepting_wsgi_req(void);
|
||||
struct wsgi_request *find_wsgi_req_by_fd(int);
|
||||
struct wsgi_request *find_wsgi_req_by_id(int);
|
||||
|
||||
void async_add_fd_write(struct wsgi_request *, int, int);
|
||||
void async_add_fd_read(struct wsgi_request *, int, int);
|
||||
|
||||
#ifdef __clang__
|
||||
struct wsgi_request *next_wsgi_req(struct wsgi_request *);
|
||||
#else
|
||||
@@ -1254,11 +1335,8 @@ inline struct wsgi_request *next_wsgi_req(struct wsgi_request *);
|
||||
#endif
|
||||
|
||||
|
||||
int async_get_timeout(void);
|
||||
void async_set_timeout(struct wsgi_request*, time_t);
|
||||
void async_add_timeout(struct wsgi_request*, int);
|
||||
void async_expire_timeouts(void);
|
||||
void async_write_all(char *, size_t);
|
||||
void async_unpause_all(void);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1273,18 +1351,11 @@ void uwsgi_close_request(struct wsgi_request *);
|
||||
|
||||
void wsgi_req_setup(struct wsgi_request *, int);
|
||||
int wsgi_req_recv(struct wsgi_request *);
|
||||
int wsgi_req_simple_recv(struct wsgi_request *);
|
||||
int wsgi_req_accept(struct wsgi_request *);
|
||||
int wsgi_req_simple_accept(struct wsgi_request *, int);
|
||||
|
||||
#ifdef UWSGI_STACKLESS
|
||||
#ifdef __clang__
|
||||
struct wsgi_request *current_wsgi_req(void);
|
||||
#else
|
||||
inline struct wsgi_request *current_wsgi_req(void);
|
||||
#endif
|
||||
#else
|
||||
#define current_wsgi_req() (*uwsgi.current_wsgi_req)()
|
||||
#endif
|
||||
|
||||
void sanitize_args(void);
|
||||
|
||||
@@ -1346,7 +1417,6 @@ int find_worker_id(pid_t);
|
||||
|
||||
|
||||
void *simple_loop(void *);
|
||||
void complex_loop(void);
|
||||
|
||||
int count_options(struct option *);
|
||||
|
||||
@@ -1367,7 +1437,7 @@ ssize_t uwsgi_sendfile(struct wsgi_request *);
|
||||
void uwsgi_register_loop(char *, void *);
|
||||
void *uwsgi_get_loop(char *);
|
||||
|
||||
void add_exported_option(int, char *);
|
||||
void add_exported_option(char *, char *, int);
|
||||
|
||||
ssize_t uwsgi_send_empty_pkt(int , char *, uint8_t , uint8_t);
|
||||
|
||||
@@ -1416,7 +1486,7 @@ int event_queue_init(void);
|
||||
void *event_queue_alloc(int);
|
||||
int event_queue_add_fd_read(int, int);
|
||||
int event_queue_add_fd_write(int, int);
|
||||
int event_queue_del_fd(int, int);
|
||||
int event_queue_del_fd(int, int, int);
|
||||
int event_queue_wait(int, int, int *);
|
||||
int event_queue_wait_multi(int, int, void *, int);
|
||||
int event_queue_interesting_fd(void *, int);
|
||||
@@ -1566,6 +1636,7 @@ int uwsgi_dict_set(struct uwsgi_dict *, char *, uint16_t, char *, uint64_t);
|
||||
|
||||
struct uwsgi_subscriber_name *uwsgi_get_subscriber(struct uwsgi_dict *, char *, uint16_t);
|
||||
|
||||
#ifndef _NO_UWSGI_RB
|
||||
#include "lib/rbtree.h"
|
||||
|
||||
struct uwsgi_rb_timer {
|
||||
@@ -1579,3 +1650,39 @@ struct uwsgi_rb_timer {
|
||||
struct rb_root *uwsgi_init_rb_timer(void);
|
||||
struct uwsgi_rb_timer *uwsgi_add_rb_timer(struct rb_root *, time_t, void *);
|
||||
struct uwsgi_rb_timer *uwsgi_min_rb_timer(struct rb_root *);
|
||||
|
||||
#endif
|
||||
|
||||
void uwsgi_nuclear_blast();
|
||||
|
||||
void uwsgi_unix_signal(int, void (*)(int));
|
||||
|
||||
char *uwsgi_get_exported_opt(char *);
|
||||
|
||||
int uwsgi_signal_add_cron(uint8_t, int, int, int, int, int);
|
||||
|
||||
char *uwsgi_get_optname_by_index(int);
|
||||
|
||||
int uwsgi_list_has_num(char *, int);
|
||||
|
||||
int uwsgi_list_has_str(char *, char *);
|
||||
|
||||
void uwsgi_cache_fix(void);
|
||||
|
||||
struct uwsgi_async_request {
|
||||
|
||||
struct wsgi_request *wsgi_req;
|
||||
struct uwsgi_async_request *prev;
|
||||
struct uwsgi_async_request *next;
|
||||
};
|
||||
|
||||
inline int event_queue_read(void);
|
||||
inline int event_queue_write(void);
|
||||
|
||||
void uwsgi_help(void);
|
||||
|
||||
void uwsgi_queue_fix(void);
|
||||
|
||||
int uwsgi_str2_num(char *);
|
||||
int uwsgi_str3_num(char *);
|
||||
int uwsgi_str4_num(char *);
|
||||
|
||||
+25
-5
@@ -2,6 +2,7 @@
|
||||
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
uwsgi_os = os.uname()[0]
|
||||
uwsgi_os_k = re.split('[-+]', os.uname()[2])[0]
|
||||
uwsgi_os_v = os.uname()[3]
|
||||
@@ -70,6 +71,9 @@ def build_uwsgi(uc):
|
||||
eplc = "-DUWSGI_LOAD_EMBEDDED_PLUGINS=\""
|
||||
for p in ep:
|
||||
p = p.rstrip().lstrip()
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
continue
|
||||
epc += "UDEP(%s);" % p
|
||||
eplc += "ULEP(%s);" % p
|
||||
epc += "\""
|
||||
@@ -92,6 +96,10 @@ def build_uwsgi(uc):
|
||||
print("*** uWSGI compiling embedded plugins ***")
|
||||
for p in ep:
|
||||
p = p.rstrip().lstrip()
|
||||
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
continue
|
||||
path = 'plugins/%s' % p
|
||||
path = path.rstrip('/')
|
||||
|
||||
@@ -208,6 +216,8 @@ class uConf(object):
|
||||
sys.exit(1)
|
||||
|
||||
def get_gcll(self):
|
||||
|
||||
self.cflags.append('-DUWSGI_BUILD_DATE="\\"%s\\""' % time.strftime("%d %B %Y %H:%M:%S"))
|
||||
kvm_list = ['FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly']
|
||||
|
||||
if uwsgi_os == 'SunOS':
|
||||
@@ -224,6 +234,9 @@ class uConf(object):
|
||||
self.libs.remove('-lpthread')
|
||||
self.libs.append('-lroot')
|
||||
|
||||
if uwsgi_os == 'Darwin':
|
||||
self.cflags.append('-mmacosx-version-min=10.5')
|
||||
|
||||
# set locking subsystem
|
||||
locking_mode = self.get('locking','auto')
|
||||
|
||||
@@ -256,7 +269,7 @@ class uConf(object):
|
||||
if int(sun_major) >= 5:
|
||||
if int(sun_minor) >= 10:
|
||||
event_mode = 'port'
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD', 'OpenBSD'):
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD', 'OpenBSD', 'NetBSD'):
|
||||
event_mode = 'kqueue'
|
||||
|
||||
if event_mode == 'epoll':
|
||||
@@ -332,7 +345,8 @@ class uConf(object):
|
||||
if self.get('udp'):
|
||||
self.cflags.append("-DUWSGI_UDP")
|
||||
|
||||
if self.get('pcre'):
|
||||
# re-enable after pcre fix
|
||||
if self.get('pcreOFF'):
|
||||
if self.get('pcre') == 'auto':
|
||||
pcreconf = spcall('pcre-config --libs')
|
||||
if pcreconf:
|
||||
@@ -374,9 +388,15 @@ class uConf(object):
|
||||
self.gcc_list.append('yaml')
|
||||
|
||||
if self.get('ldap'):
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
if self.get('ldap') == 'auto':
|
||||
if os.path.exists('/usr/include/ldap.h'):
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
else:
|
||||
self.cflags.append("-DUWSGI_LDAP")
|
||||
self.gcc_list.append('ldap')
|
||||
self.libs.append('-lldap')
|
||||
|
||||
if self.get('evdis'):
|
||||
self.cflags.append("-DUWSGI_EVDIS")
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[uwsgi]
|
||||
|
||||
trac = trac.web.main
|
||||
id = myapp
|
||||
socket = /tmp/%(id).sock
|
||||
env = TRAC_ENV=/opt/projects/%(id)
|
||||
module = %(trac):dispatch_request
|
||||
processes = 8
|
||||
master = true
|
||||
@@ -0,0 +1,31 @@
|
||||
<uwsgi>
|
||||
|
||||
<id>app001</id>
|
||||
|
||||
<print>starting dir is %v</print>
|
||||
|
||||
<chdir>%v/../</chdir>
|
||||
<localhost>127.0.0.1</localhost>
|
||||
|
||||
<socket>%(localhost):3031</socket>
|
||||
<socket>/tmp/%(id).sock</socket>
|
||||
|
||||
<cpus>4</cpus>
|
||||
<werkzeug>werkzeug.testapp:test_app</werkzeug>
|
||||
|
||||
<master/>
|
||||
|
||||
<vhost/>
|
||||
<vhost-host/>
|
||||
|
||||
<processes>%(cpus)</processes>
|
||||
|
||||
<app domain="sirius001:9090">
|
||||
<script>werkzeug.testapp:test_app</script>
|
||||
</app>
|
||||
|
||||
<app domain="sirius002:9090">
|
||||
<script>uwsgicc</script>
|
||||
</app>
|
||||
|
||||
</uwsgi>
|
||||
@@ -18,12 +18,11 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag, char *magic_ta
|
||||
xmlChar *xml_uwsgi_mountpoint = NULL;
|
||||
xmlChar *xml_uwsgi_domain = NULL;
|
||||
xmlChar *node_mode;
|
||||
struct option *lopt, *aopt;
|
||||
|
||||
char *colon;
|
||||
|
||||
char *xml_id;
|
||||
int i;
|
||||
char *xml_id;
|
||||
char *xml_content;
|
||||
int xml_size = 0;
|
||||
|
||||
@@ -105,52 +104,26 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag, char *magic_ta
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp((char *) node->name, aopt->name)) {
|
||||
if (!node->children && aopt->has_arg) {
|
||||
uwsgi_log( "[uWSGI] %s option need a value. skip.\n", aopt->name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (node->children) {
|
||||
if (!node->children->content && aopt->has_arg) {
|
||||
uwsgi_log( "[uWSGI] %s option need a value. skip.\n", aopt->name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
node_mode = xmlGetProp(node, (const xmlChar *) "mode");
|
||||
if (uwsgi.mode && node_mode) {
|
||||
if (strcmp(uwsgi.mode, (char *) node_mode)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
node_mode = xmlGetProp(node, (const xmlChar *) "mode");
|
||||
if (uwsgi.mode && node_mode) {
|
||||
if (strcmp(uwsgi.mode, (char *) node_mode)) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id");
|
||||
if (colon && xml_id) {
|
||||
if (strcmp(colon, xml_id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id");
|
||||
if (colon && xml_id) {
|
||||
if (strcmp(colon, xml_id)) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char *) node->name);
|
||||
}
|
||||
else {
|
||||
if (node->children) {
|
||||
manage_opt(aopt->val, (char *) node->children->content);
|
||||
}
|
||||
else {
|
||||
manage_opt(aopt->val, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
next:
|
||||
lopt++;
|
||||
if (node->children) {
|
||||
add_exported_option((char *) node->name, (char *) node->children->content, 0);
|
||||
}
|
||||
else {
|
||||
add_exported_option((char *) node->name, "1", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,7 +358,7 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, struct option *long_options
|
||||
|
||||
xmlfd = open(uwsgi.xml_config, O_RDONLY);
|
||||
if (xmlfd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(uwsgi.xml_config);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
|
||||
int lines = 1;
|
||||
|
||||
struct option *lopt, *aopt;
|
||||
char *section_asked = "uwsgi";
|
||||
char *colon;
|
||||
|
||||
@@ -171,26 +170,7 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) {
|
||||
|
||||
//uwsgi_log("YAML: %s = %s\n", key, val);
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
while ((aopt = lopt)) {
|
||||
if (!aopt->name)
|
||||
break;
|
||||
if (!strcmp(key, aopt->name)) {
|
||||
if (aopt->flag) {
|
||||
*aopt->flag = aopt->val;
|
||||
add_exported_option(0, (char *)key);
|
||||
}
|
||||
else {
|
||||
if (aopt->has_arg == optional_argument) {
|
||||
if (!strcmp("true", val)) {
|
||||
val = NULL;
|
||||
}
|
||||
}
|
||||
manage_opt(aopt->val, val);
|
||||
}
|
||||
}
|
||||
lopt++;
|
||||
}
|
||||
add_exported_option((char *)key, val, 0);
|
||||
}
|
||||
next:
|
||||
len -= (yaml_line - yaml);
|
||||
|
||||
Reference in New Issue
Block a user