mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -11,3 +11,5 @@ b8f67c6cd0d62f864db9b2b265b4e260ad7d873c 0.9.6-rc2
|
||||
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
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
*** march 2011 ***
|
||||
|
||||
* 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
|
||||
|
||||
@@ -2,198 +2,365 @@
|
||||
|
||||
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();
|
||||
|
||||
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,7 +13,7 @@ sendfile = true
|
||||
minterpreters = true
|
||||
async = true
|
||||
evdis = false
|
||||
ldap = false
|
||||
ldap = auto
|
||||
pcre = auto
|
||||
debug = false
|
||||
unbit = false
|
||||
@@ -21,7 +21,7 @@ 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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -222,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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ void uwsgi_lock_init(void *lock) {
|
||||
|
||||
int fd = open(filename, O_CREAT|O_RDWR|O_TRUNC);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open(filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -206,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);
|
||||
|
||||
@@ -288,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
|
||||
@@ -317,6 +330,13 @@ 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()");
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
//uwsgi_log("ready_to_reload %d %d\n", ready_to_reload, uwsgi.numproc);
|
||||
|
||||
@@ -606,6 +626,20 @@ void master_loop(char **argv, char **environ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#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) {
|
||||
@@ -709,7 +743,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
|
||||
@@ -911,6 +944,12 @@ 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()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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']
|
||||
@@ -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);
|
||||
@@ -555,12 +561,16 @@ void http_loop() {
|
||||
|
||||
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++) {
|
||||
@@ -726,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;
|
||||
@@ -743,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);
|
||||
@@ -768,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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -478,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)) {
|
||||
|
||||
@@ -35,6 +35,26 @@ 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"},
|
||||
{"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);
|
||||
@@ -176,7 +196,7 @@ PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {
|
||||
real_filename = uwsgi_concat2(filename, "/__init__.py");
|
||||
pyfile = fopen(real_filename, "r");
|
||||
if (!pyfile) {
|
||||
uwsgi_error("fopen()");
|
||||
uwsgi_error_open(real_filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -690,6 +710,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();
|
||||
@@ -821,9 +846,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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -938,9 +968,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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -972,8 +1007,7 @@ struct uwsgi_plugin python_plugin = {
|
||||
.rpc = uwsgi_python_rpc,
|
||||
|
||||
.spooler = uwsgi_python_spooler,
|
||||
/*
|
||||
.help = uwsgi_python_help,
|
||||
*/
|
||||
|
||||
.help = uwsgi_python_help,
|
||||
|
||||
};
|
||||
|
||||
@@ -813,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("");
|
||||
@@ -2087,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;
|
||||
}
|
||||
|
||||
@@ -2242,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;
|
||||
@@ -2641,6 +2641,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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -398,8 +392,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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+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,
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
#include "uwsgi.h"
|
||||
|
||||
#ifdef UWSGI_STACKLESS
|
||||
#include <stackless_api.h>
|
||||
#endif
|
||||
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
struct wsgi_request* find_request_by_tasklet(PyTaskletObject *tasklet) {
|
||||
|
||||
+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)
|
||||
|
||||
@@ -104,7 +104,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 +155,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 +269,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 +295,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) {
|
||||
@@ -376,6 +376,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);
|
||||
@@ -408,7 +409,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();
|
||||
@@ -426,9 +429,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];
|
||||
|
||||
@@ -443,6 +443,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;
|
||||
@@ -547,21 +566,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) {
|
||||
@@ -1058,7 +1062,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);
|
||||
}
|
||||
}
|
||||
@@ -1353,7 +1357,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);
|
||||
}
|
||||
|
||||
@@ -1612,3 +1616,53 @@ char *uwsgi_get_exported_opt(char *key) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ static struct option long_base_options[] = {
|
||||
{"sharedarea", required_argument, 0, 'A'},
|
||||
{"cache", required_argument, 0, LONG_ARGS_CACHE},
|
||||
{"cache-blocksize", required_argument, 0, LONG_ARGS_CACHE_BLOCKSIZE},
|
||||
{"cache-store", required_argument, 0, LONG_ARGS_CACHE_STORE},
|
||||
{"cache-store-sync", required_argument, 0, LONG_ARGS_CACHE_STORE_SYNC},
|
||||
{"queue", required_argument, 0, LONG_ARGS_QUEUE},
|
||||
{"queue-blocksize", required_argument, 0, LONG_ARGS_QUEUE_BLOCKSIZE},
|
||||
#ifdef UWSGI_SPOOLER
|
||||
@@ -95,6 +97,7 @@ static struct option long_base_options[] = {
|
||||
{"limit-post", required_argument, 0, LONG_ARGS_LIMIT_POST},
|
||||
{"no-orphans", no_argument, &uwsgi.no_orphans, 1},
|
||||
{"prio", required_argument, 0, LONG_ARGS_PRIO},
|
||||
{"cpu-affinity", required_argument, 0, LONG_ARGS_CPU_AFFINITY},
|
||||
{"post-buffering", required_argument, 0, LONG_ARGS_POST_BUFFERING},
|
||||
{"post-buffering-bufsize", required_argument, 0, LONG_ARGS_POST_BUFFERING_SIZE},
|
||||
{"upload-progress", required_argument, 0, LONG_ARGS_UPLOAD_PROGRESS},
|
||||
@@ -112,7 +115,7 @@ static struct option long_base_options[] = {
|
||||
{"cluster-log", required_argument, 0, LONG_ARGS_CLUSTER_LOG},
|
||||
{"subscribe-to", required_argument, 0, LONG_ARGS_SUBSCRIBE_TO},
|
||||
#ifdef UWSGI_SNMP
|
||||
{"snmp", no_argument, 0, LONG_ARGS_SNMP},
|
||||
{"snmp", optional_argument, 0, LONG_ARGS_SNMP},
|
||||
{"snmp-community", required_argument, 0, LONG_ARGS_SNMP_COMMUNITY},
|
||||
#endif
|
||||
{"check-interval", required_argument, 0, LONG_ARGS_CHECK_INTERVAL},
|
||||
@@ -153,11 +156,14 @@ static struct option long_base_options[] = {
|
||||
{"cgroup-opt", required_argument, 0, LONG_ARGS_CGROUP_OPT},
|
||||
{"namespace", required_argument, 0, LONG_ARGS_LINUX_NS},
|
||||
{"ns", required_argument, 0, LONG_ARGS_LINUX_NS},
|
||||
{"namespace-net", required_argument, 0, LONG_ARGS_LINUX_NS_NET},
|
||||
{"ns-net", required_argument, 0, LONG_ARGS_LINUX_NS_NET},
|
||||
#endif
|
||||
{"loop", required_argument, 0, LONG_ARGS_LOOP},
|
||||
{"worker-exec", required_argument, 0, LONG_ARGS_WORKER_EXEC},
|
||||
{"attach-daemon", required_argument, 0, LONG_ARGS_ATTACH_DAEMON},
|
||||
{"plugins", required_argument, 0, LONG_ARGS_PLUGINS},
|
||||
{"allowed-modifiers", required_argument, 0, LONG_ARGS_ALLOWED_MODIFIERS},
|
||||
{"remap-modifier", required_argument, 0, LONG_ARGS_REMAP_MODIFIER},
|
||||
{"dump-options", no_argument, &uwsgi.dump_options, 1},
|
||||
{"show-config", no_argument, &uwsgi.show_config, 1},
|
||||
@@ -182,7 +188,7 @@ void warn_pipe()
|
||||
{
|
||||
struct wsgi_request *wsgi_req = current_wsgi_req();
|
||||
|
||||
if (uwsgi.async < 2 && wsgi_req->uri_len > 0) {
|
||||
if (uwsgi.threads < 2 && wsgi_req->uri_len > 0) {
|
||||
uwsgi_log("SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request %.*s (ip %.*s) !!!\n", wsgi_req->uri_len, wsgi_req->uri, wsgi_req->remote_addr_len, wsgi_req->remote_addr);
|
||||
} else {
|
||||
uwsgi_log("SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) !!!\n");
|
||||
@@ -448,6 +454,7 @@ int main(int argc, char *argv[], char *envp[])
|
||||
|
||||
char *emperor_env;
|
||||
char *magic_table[0xff];
|
||||
char *optname;
|
||||
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
@@ -583,17 +590,26 @@ int main(int argc, char *argv[], char *envp[])
|
||||
}
|
||||
build_options();
|
||||
|
||||
uwsgi.option_index = -1;
|
||||
while ((i = getopt_long(argc, argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
|
||||
if (i == 0) {
|
||||
add_exported_option((char *)uwsgi.long_options[uwsgi.option_index].name, "1", 0);
|
||||
|
||||
if (uwsgi.option_index > -1) {
|
||||
optname = (char *)uwsgi.long_options[uwsgi.option_index].name;
|
||||
}
|
||||
else {
|
||||
add_exported_option((char *)uwsgi.long_options[uwsgi.option_index].name, optarg, 1);
|
||||
optname = uwsgi_get_optname_by_index(i);
|
||||
}
|
||||
// is this a flagged option ?
|
||||
if (i == 0) {
|
||||
add_exported_option(optname, "1", 0);
|
||||
}
|
||||
else {
|
||||
add_exported_option(optname, optarg, 1);
|
||||
manage_opt(i, optarg);
|
||||
}
|
||||
uwsgi.option_index = -1;
|
||||
}
|
||||
|
||||
|
||||
if (optind < argc) {
|
||||
char *lazy = argv[optind];
|
||||
if (lazy[0] != '[') {
|
||||
@@ -897,7 +913,7 @@ options_parsed:
|
||||
uwsgi_log("writing pidfile to %s\n", uwsgi.pidfile);
|
||||
pidfile = fopen(uwsgi.pidfile, "w");
|
||||
if (!pidfile) {
|
||||
uwsgi_error("fopen");
|
||||
uwsgi_error_open(uwsgi.pidfile);
|
||||
exit(1);
|
||||
}
|
||||
if (fprintf(pidfile, "%d\n", (int) getpid()) < 0) {
|
||||
@@ -924,7 +940,9 @@ options_parsed:
|
||||
char stack[PTHREAD_STACK_MIN];
|
||||
int waitpid_status;
|
||||
uwsgi_log("*** jailing uWSGI in %s ***\n", uwsgi.ns);
|
||||
pid_t pid = clone(uwsgi_start, stack+PTHREAD_STACK_MIN, SIGCHLD|CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS, (void *)argv);
|
||||
int clone_flags = SIGCHLD|CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
|
||||
//clone_flags |= CLONE_NEWNET;
|
||||
pid_t pid = clone(uwsgi_start, stack+PTHREAD_STACK_MIN, clone_flags, (void *)argv);
|
||||
if (pid == -1) {
|
||||
uwsgi_error("clone()");
|
||||
exit(1);
|
||||
@@ -1152,9 +1170,10 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
|
||||
uwsgi_register_loop("simple", simple_loop);
|
||||
uwsgi_register_loop("async", complex_loop);
|
||||
uwsgi_register_loop("async", async_loop);
|
||||
|
||||
|
||||
// TODO rewrite to use uwsgi.max_fd
|
||||
if (uwsgi.async > 1) {
|
||||
if (!getrlimit(RLIMIT_NOFILE, &uwsgi.rl)) {
|
||||
if ((unsigned long) uwsgi.rl.rlim_cur < (unsigned long) uwsgi.async) {
|
||||
@@ -1191,8 +1210,8 @@ int uwsgi_start(void *v_argv) {
|
||||
uwsgi.async_buf = uwsgi_malloc(sizeof(char *) * uwsgi.cores);
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
uwsgi_log("%d\n", uwsgi.max_fd);
|
||||
uwsgi.async_waiting_fd_table = malloc( sizeof(int) * uwsgi.max_fd);
|
||||
uwsgi_log("async fd table size: %d\n", uwsgi.max_fd);
|
||||
uwsgi.async_waiting_fd_table = malloc( sizeof(struct wsgi_request *) * uwsgi.max_fd);
|
||||
if (!uwsgi.async_waiting_fd_table) {
|
||||
uwsgi_error("malloc()");
|
||||
exit(1);
|
||||
@@ -1329,26 +1348,65 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
memset(uwsgi.cache_unused_stack, 0, sizeof(uint64_t) * uwsgi.cache_max_items);
|
||||
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
// the first cache item is always zero
|
||||
uwsgi.shared->cache_first_available_item = 1;
|
||||
uwsgi.shared->cache_unused_stack_ptr = 0;
|
||||
|
||||
//uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (uwsgi.cache_store) {
|
||||
uwsgi.cache_filesize = (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items);
|
||||
int cache_fd;
|
||||
struct stat cst;
|
||||
|
||||
if (stat(uwsgi.cache_store, &cst)) {
|
||||
uwsgi_log("creating a new cache store file: %s\n", uwsgi.cache_store);
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR );
|
||||
if (cache_fd >= 0) {
|
||||
// fill the caching store
|
||||
if (ftruncate(cache_fd, uwsgi.cache_filesize)) {
|
||||
uwsgi_log("ftruncate()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((size_t)cst.st_size != uwsgi.cache_filesize || !S_ISREG(cst.st_mode)) {
|
||||
uwsgi_log("invalid cache store file. Please remove it or fix cache blocksize/items to match its size\n");
|
||||
exit(1);
|
||||
}
|
||||
cache_fd = open(uwsgi.cache_store, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR );
|
||||
uwsgi_log("recovered cache from backing store file: %s\n", uwsgi.cache_store);
|
||||
}
|
||||
|
||||
if (cache_fd < 0) {
|
||||
uwsgi_error_open(uwsgi.cache_store);
|
||||
exit(1);
|
||||
}
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, uwsgi.cache_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, cache_fd, 0);
|
||||
uwsgi_cache_fix();
|
||||
|
||||
}
|
||||
else {
|
||||
uwsgi.cache_items = (struct uwsgi_cache_item *) mmap(NULL, (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
for(i=0;i< (int) uwsgi.cache_max_items;i++) {
|
||||
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
|
||||
}
|
||||
}
|
||||
if (!uwsgi.cache_items) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
uwsgi.cache = mmap(NULL, uwsgi.cache_blocksize * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
|
||||
if (!uwsgi.cache) {
|
||||
uwsgi_error("mmap()");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
|
||||
uwsgi.cache = ((void *) uwsgi.cache_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items) ;
|
||||
|
||||
for(i=0;i< (int) uwsgi.cache_max_items;i++) {
|
||||
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
|
||||
}
|
||||
|
||||
// the first cache item is always zero
|
||||
uwsgi.shared->cache_first_available_item = 1;
|
||||
uwsgi.shared->cache_unused_stack_ptr = 0;
|
||||
|
||||
uwsgi.cache_lock = uwsgi_mmap_shared_rwlock();
|
||||
uwsgi_rwlock_init(uwsgi.cache_lock);
|
||||
|
||||
@@ -1520,7 +1578,7 @@ int uwsgi_start(void *v_argv) {
|
||||
} else {
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
uwsgi_error("open()");
|
||||
uwsgi_error_open("/dev/null");
|
||||
exit(1);
|
||||
}
|
||||
if (fd != 0) {
|
||||
@@ -1617,20 +1675,6 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_ASYNC
|
||||
if (uwsgi.async > 1) {
|
||||
#ifdef __linux__
|
||||
uwsgi.async_events = uwsgi_malloc(sizeof(struct epoll_event) * uwsgi.async);
|
||||
#elif defined(__sun__)
|
||||
uwsgi.async_events = uwsgi_malloc(sizeof(struct pollfd) * uwsgi.async);
|
||||
#else
|
||||
uwsgi.async_events = uwsgi_malloc(sizeof(struct kevent) * uwsgi.async);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef UNBIT
|
||||
uwsgi_log("your server socket listen backlog is limited to %d connections\n", uwsgi.listen_queue);
|
||||
@@ -1717,12 +1761,6 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
|
||||
uwsgi_rawlog(" ***\n");
|
||||
|
||||
#ifdef UWSGI_SNMP
|
||||
if (uwsgi.snmp) {
|
||||
//snmp_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
//init apps hook
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->init_apps) {
|
||||
@@ -1730,6 +1768,12 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->init_apps) {
|
||||
uwsgi.gp[i]->init_apps();
|
||||
}
|
||||
}
|
||||
|
||||
/*parse xml for <app> tags */
|
||||
#ifdef UWSGI_XML
|
||||
if (uwsgi.xml_round2 && uwsgi.xml_config != NULL) {
|
||||
@@ -1776,6 +1820,20 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
uwsgi_log("spawned uWSGI master process (pid: %d)\n", uwsgi.mypid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// security in multiuser environment: allow only a subset of modifiers
|
||||
if (uwsgi.allowed_modifiers) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (!uwsgi_list_has_num(uwsgi.allowed_modifiers, i)) {
|
||||
uwsgi.p[i]->request = unconfigured_hook;
|
||||
uwsgi.p[i]->after_request = unconfigured_after_hook;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef UWSGI_SPOOLER
|
||||
if (uwsgi.spool_dir != NULL && uwsgi.sockets_cnt > 0) {
|
||||
uwsgi.shared->spooler_pid = spooler_start();
|
||||
@@ -1836,6 +1894,29 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
//from now on the process is a real worker
|
||||
}
|
||||
|
||||
if (uwsgi.cpu_affinity) {
|
||||
#ifdef __linux__
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
int ncpu = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
int base_cpu = (uwsgi.mywid-1)*uwsgi.cpu_affinity;
|
||||
if (base_cpu >= ncpu) {
|
||||
base_cpu = base_cpu % ncpu;
|
||||
}
|
||||
uwsgi_log("set cpu affinity for worker %d to", uwsgi.mywid);
|
||||
for(i=0;i<uwsgi.cpu_affinity;i++) {
|
||||
if (base_cpu >= ncpu) base_cpu = 0 ;
|
||||
CPU_SET(base_cpu, &cpuset);
|
||||
uwsgi_log(" %d", base_cpu);
|
||||
base_cpu++;
|
||||
}
|
||||
if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) {
|
||||
uwsgi_error("sched_setaffinity()");
|
||||
}
|
||||
uwsgi_log("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (uwsgi.worker_exec) {
|
||||
char *w_argv[2];
|
||||
w_argv[0] = uwsgi.worker_exec;
|
||||
@@ -1881,6 +1962,16 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
event_queue_add_fd_read(uwsgi.async_queue, uwsgi.sockets[i].fd);
|
||||
}
|
||||
}
|
||||
|
||||
uwsgi.rb_async_timeouts = uwsgi_init_rb_timer();
|
||||
|
||||
uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request*) * uwsgi.async);
|
||||
|
||||
for(i=0;i<uwsgi.async;i++) {
|
||||
uwsgi.async_queue_unused[i] = uwsgi.wsgi_requests[i];
|
||||
}
|
||||
|
||||
uwsgi.async_queue_unused_ptr = uwsgi.async-1;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1918,6 +2009,7 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
//re - initialize wsgi_req(can be full of init_uwsgi_app data)
|
||||
for (i = 0; i < uwsgi.cores; i++) {
|
||||
memset(uwsgi.wsgi_requests[i], 0, sizeof(struct wsgi_request));
|
||||
uwsgi.wsgi_requests[i]->async_id = i;
|
||||
}
|
||||
|
||||
|
||||
@@ -1949,6 +2041,7 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
uwsgi.sockets_poll[uwsgi.sockets_cnt].fd = uwsgi.shared->worker_signal_pipe[1];
|
||||
uwsgi.sockets_poll[uwsgi.sockets_cnt].events = POLLIN;
|
||||
#ifdef UWSGI_ASYNC
|
||||
// add uwsgi signal fd to async queue
|
||||
if (uwsgi.async > 1) {
|
||||
event_queue_add_fd_read(uwsgi.async_queue, uwsgi.sockets_poll[uwsgi.sockets_cnt].fd);
|
||||
}
|
||||
@@ -1993,7 +2086,7 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
|
||||
long y = 0;
|
||||
simple_loop((void *) y);
|
||||
} else {
|
||||
complex_loop();
|
||||
async_loop(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2038,6 +2131,9 @@ end:
|
||||
case LONG_ARGS_REMAP_MODIFIER:
|
||||
uwsgi.remap_modifier = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_ALLOWED_MODIFIERS:
|
||||
uwsgi.allowed_modifiers = optarg;
|
||||
return 1;
|
||||
case LONG_ARGS_PLUGINS:
|
||||
p = strtok(optarg, ",");
|
||||
while (p != NULL) {
|
||||
@@ -2047,7 +2143,7 @@ end:
|
||||
uwsgi_load_plugin(-1, p, NULL, 0);
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
build_options();
|
||||
build_options();
|
||||
return 1;
|
||||
case LONG_ARGS_CHDIR:
|
||||
uwsgi.chdir = optarg;
|
||||
@@ -2110,6 +2206,10 @@ end:
|
||||
#ifdef UWSGI_SNMP
|
||||
case LONG_ARGS_SNMP:
|
||||
uwsgi.snmp = 1;
|
||||
if (optarg) {
|
||||
uwsgi.snmp_addr = optarg;
|
||||
uwsgi.master_process = 1;
|
||||
}
|
||||
return 1;
|
||||
case LONG_ARGS_SNMP_COMMUNITY:
|
||||
uwsgi.snmp = 1;
|
||||
@@ -2212,6 +2312,9 @@ end:
|
||||
case LONG_ARGS_PRIO:
|
||||
uwsgi.prio = (int) strtol(optarg, NULL, 10);
|
||||
return 1;
|
||||
case LONG_ARGS_CPU_AFFINITY:
|
||||
uwsgi.cpu_affinity = (int) strtol(optarg, NULL, 10);
|
||||
return 1;
|
||||
case LONG_ARGS_POST_BUFFERING:
|
||||
uwsgi.post_buffering = atoi(optarg);
|
||||
return 1;
|
||||
@@ -2237,6 +2340,13 @@ end:
|
||||
case LONG_ARGS_CACHE:
|
||||
uwsgi.cache_max_items = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_STORE:
|
||||
uwsgi.cache_store = optarg;
|
||||
uwsgi.master_process = 1;
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_STORE_SYNC:
|
||||
uwsgi.cache_store_sync = atoi(optarg);
|
||||
return 1;
|
||||
case LONG_ARGS_CACHE_BLOCKSIZE:
|
||||
uwsgi.cache_blocksize = atoi(optarg);
|
||||
return 1;
|
||||
@@ -2320,6 +2430,7 @@ end:
|
||||
return 1;
|
||||
case 'p':
|
||||
if (!strcmp(optarg, "auto")) {
|
||||
#ifndef __sun__
|
||||
struct rlimit rl;
|
||||
if (getrlimit(RLIMIT_NPROC, &rl)) {
|
||||
uwsgi_error("getrlimit()");
|
||||
@@ -2346,6 +2457,9 @@ end:
|
||||
uwsgi.master_process = 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
uwsgi.numproc = 4;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
uwsgi.numproc = atoi(optarg);
|
||||
@@ -2413,104 +2527,11 @@ end:
|
||||
uwsgi.single_interpreter = 1;
|
||||
return 1;
|
||||
case 'h':
|
||||
uwsgi_help();
|
||||
/*
|
||||
fprintf(stdout, "Usage: %s [options...]\n\
|
||||
\t-s|--socket <name>\t\tpath (or name) of UNIX/TCP socket to bind to\n\
|
||||
\t-l|--listen <num>\t\tset socket listen queue to <n> (default 64, maximum is system dependent)\n\
|
||||
\t-z|--socket-timeout <sec>\tset socket timeout to <sec> seconds (default 4 seconds)\n\
|
||||
\t-b|--buffer-size <n>\t\tset buffer size to <n> bytes\n\
|
||||
\t-L|--disable-logging\t\tdisable request logging (only errors or server messages will be logged)\n\
|
||||
\t-x|--xmlconfig <path>\t\tpath of xml config file\n\
|
||||
\t-w|--module <module>\t\tname of python config module\n\
|
||||
\t-t|--harakiri <sec>\t\tset harakiri timeout to <sec> seconds\n\
|
||||
\t-p|--processes <n>\t\tspawn <n> uwsgi worker processes\n\
|
||||
\t-O|--optimize <n>\t\tset python optimization level to <n>\n\
|
||||
\t-v|--max-vars <n>\t\tset maximum number of vars/headers to <n>\n\
|
||||
\t-A|--sharedarea <n>\t\tcreate a shared memory area of <n> pages\n\
|
||||
\t-c|--cgi-mode\t\t\tset cgi mode\n\
|
||||
\t-C|--chmod-socket[=NNN]\t\tchmod socket to 666 or NNN\n\
|
||||
\t-m|--memory-report\t\tenable memory usage report\n\
|
||||
\t-i|--single-interpreter\t\tsingle interpreter mode\n\
|
||||
\t-a|--abstract-socket\t\tset socket in the abstract namespace (Linux only)\n\
|
||||
\t-T|--enable-threads\t\tenable threads support\n\
|
||||
\t-M|--master\t\t\tenable master process manager\n\
|
||||
\t-H|--home <path>\t\tset python home/virtualenv\n\
|
||||
\t-h|--help\t\t\tthis help\n\
|
||||
\t-r|--reaper\t\t\tprocess reaper (call waitpid(-1,...) after each request)\n\
|
||||
\t-R|--max-requests\t\tmaximum number of requests for each worker\n\
|
||||
\t-j|--test\t\t\ttest if uWSGI can import a module\n\
|
||||
\t-Q|--spooler <dir>\t\trun the spooler on directory <dir>\n\
|
||||
\t--callable <callable>\t\tset the callable (default 'application')\n\
|
||||
\t--pidfile <file>\t\twrite the masterpid to <file>\n\
|
||||
\t--chroot <dir>\t\t\tchroot to directory <dir> (only root)\n\
|
||||
\t--gid <id/groupname>\t\tsetgid to <id/groupname> (only root)\n\
|
||||
\t--uid <id/username>\t\tsetuid to <id/username> (only root)\n\
|
||||
\t--chdir <dir>\t\t\tchdir to <dir> before app loading\n\
|
||||
\t--chdir2 <dir>\t\t\tchdir to <dir> after module loading\n\
|
||||
\t--no-server\t\t\tinitialize the uWSGI server then exit. Useful for testing and using uwsgi embedded module\n\
|
||||
\t--no-defer-accept\t\tdisable the no-standard way to defer the accept() call (TCP_DEFER_ACCEPT, SO_ACCEPTFILTER...)\n\
|
||||
\t--paste <config:/egg:>\t\tload applications using paste.deploy.loadapp()\n\
|
||||
\t--check-interval <sec>\t\tset the check interval (in seconds) of the master process\n\
|
||||
\t--pythonpath <dir>\t\tadd <dir> to PYTHONPATH\n\
|
||||
\t--python-path <dir>\t\tadd <dir> to PYTHONPATH\n\
|
||||
\t--pp <dir>\t\t\tadd <dir> to PYTHONPATH\n\
|
||||
\t--pyargv <args>\t\t\tassign args to python sys.argv\n\
|
||||
\t--limit-as <MB>\t\t\tlimit the address space of processes to MB megabytes\n\
|
||||
\t--limit-post <bytes>\t\tlimit HTTP content_length size to <bytes>\n\
|
||||
\t--post-buffering <bytes>\tbuffer HTTP POST request higher than <bytes> to disk\n\
|
||||
\t--post-buffering-bufsize <b>\tset the buffer size to <b> bytes for post-buffering\n\
|
||||
\t--prio <N>\t\t\tset process priority/nice to N\n\
|
||||
\t--no-orphans\t\t\tautomatically kill workers on master's dead\n\
|
||||
\t--udp <ip:port>\t\t\tbind master process to udp socket on ip:port\n\
|
||||
\t--multicast <group>\t\tset multicast group\n\
|
||||
\t--snmp\t\t\t\tenable SNMP support in the UDP server\n\
|
||||
\t--snmp-community <value>\tset SNMP community code to <value>\n\
|
||||
\t--erlang <name@ip>\t\tenable the Erlang server with node name <node@ip>\n\
|
||||
\t--erlang-cookie <cookie>\tset the erlang cookie to <cookie>\n\
|
||||
\t--nagios\t\t\tdo a nagios check\n\
|
||||
\t--binary-path <bin-path>\tset the path for the next reload of uWSGI (needed for chroot environments)\n\
|
||||
\t--proxy <socket>\t\trun the uwsgi proxy on socket <socket>\n\
|
||||
\t--proxy-node <socket>\t\tadd the node <socket> to the proxy\n\
|
||||
\t--proxy-max-connections <n>\tset the max number of concurrent connections mnaged by the proxy\n\
|
||||
\t--wsgi-file <file>\t\tload the <file> wsgi file\n\
|
||||
\t--file <file>\t\t\tuse python file instead of python module for configuration\n\
|
||||
\t--eval <code>\t\t\tevaluate code for app configuration\n\
|
||||
\t--async <n>\t\t\tenable async mode with n core\n\
|
||||
\t--logto <logfile|addr>\t\tlog to file/udp\n\
|
||||
\t--logdate\t\t\tadd timestamp to loglines\n\
|
||||
\t--log-zero\t\t\tlog requests with 0 response size\n\
|
||||
\t--log-slow <t>\t\t\tlog requests slower than <t> milliseconds\n\
|
||||
\t--log-4xx\t\t\tlog requests with status code 4xx\n\
|
||||
\t--log-5xx\t\t\tlog requests with status code 5xx\n\
|
||||
\t--log-big <n>\t\t\tlog requests bigger than <n> bytes\n\
|
||||
\t--log-sendfile\t\t\tlog sendfile() requests\n\
|
||||
\t--ignore-script-name\t\tdisable uWSGI management of SCRIPT_NAME\n\
|
||||
\t--no-default-app\t\tdo not fallback unknown SCRIPT_NAME requests\n\
|
||||
\t--ini <inifile>\t\t\tpath of ini config file\n\
|
||||
\t--ini-paste <inifile>\t\tpath of ini config file that contains paste configuration\n\
|
||||
\t--ldap <url>\t\t\turl of LDAP uWSGIConfig resource\n\
|
||||
\t--ldap-schema\t\t\tdump uWSGIConfig LDAP schema\n\
|
||||
\t--ldap-schema-ldif\t\tdump uWSGIConfig LDAP schema in LDIF format\n\
|
||||
\t--grunt\t\t\t\tenable grunt workers\n\
|
||||
\t--ugreen\t\t\tenable uGreen support\n\
|
||||
\t--ugreen-stacksize <n>\t\tset uGreen stacksize to <n>\n\
|
||||
\t--stackless\t\t\tenable usage of tasklet (only on Stackless Python)\n\
|
||||
\t--no-site\t\t\tdo not import site.py on startup\n\
|
||||
\t--vhost\t\t\t\tenable virtual hosting\n\
|
||||
\t--mount MOUNTPOINT=app\t\tadda new app under MOUNTPOINT\n\
|
||||
\t--routing\t\t\tenable uWSGI advanced routing\n\
|
||||
\t--http <addr>\t\t\tstart embedded HTTP server on <addr>\n\
|
||||
\t--http-only\t\t\tstart only the embedded HTTP server\n\
|
||||
\t--http-var KEY[=VALUE]\t\tadd var KEY to uwsgi requests made by the embedded HTTP server\n\
|
||||
\t--catch-exceptions\t\tprint exceptions in the browser\n\
|
||||
\t--mode\t\t\t\tset configuration mode\n\
|
||||
\t--env KEY=VALUE\t\t\tset environment variable\n\
|
||||
\t--vacuum\t\t\tclear the environment on exit (remove UNIX sockets and pidfiles)\n\
|
||||
\t--ping <addr>\t\t\tping a uWSGI server (returns 1 on failure 0 on success)\n\
|
||||
\t--ping-timeout <n>\t\tset ping timeout to <n>\n\
|
||||
\t--cgroup <group>\t\trun the server in <group> cgroup (Linux only)\n\
|
||||
\t--cgroup-opt KEY=VAL\t\tset cgroup option (Linux only)\n\
|
||||
\t--version\t\t\tprint server version\n\
|
||||
\t-d|--daemonize <logfile|addr>\tdaemonize and log into <logfile> or udp <addr>\n", uwsgi.binary_path);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2963,3 +2984,245 @@ char *uwsgi_cluster_best_node() {
|
||||
uwsgi.shared->nodes[best_node].last_choosen = time(NULL);
|
||||
return uwsgi.shared->nodes[best_node].name;
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_help_item main_help[] = {
|
||||
|
||||
{"socket <name>", "path (or name) of UNIX/TCP socket to bind to"},
|
||||
{"listen <num>", "set socket listen queue to <n> (default 100, maximum is system dependent)"},
|
||||
{"socket-timeout <sec>", "set socket timeout to <sec> seconds (default 4 seconds)"},
|
||||
{"buffer-size <n>", "set buffer size to <n> bytes"},
|
||||
{"disable-logging", "disable request logging (only errors or server messages will be logged)"},
|
||||
{"xmlconfig <path>", "path of xml config file"},
|
||||
{"harakiri <sec>", "set harakiri timeout to <sec> seconds"},
|
||||
{"processes <n>", "spawn <n> uwsgi worker processes"},
|
||||
{"max-vars <n>", "set maximum number of vars/headers to <n>"},
|
||||
{"sharedarea <n>", "create a shared memory area of <n> pages"},
|
||||
{"cgi-mode", "set cgi mode"},
|
||||
{"chmod-socket[=NNN]", "chmod socket to 666 or NNN"},
|
||||
{"memory-report", "enable memory usage report"},
|
||||
{"single-interpreter", "single interpreter mode"},
|
||||
{"abstract-socket", "set socket in the abstract namespace (Linux only)"},
|
||||
{"enable-threads", "enable threads support"},
|
||||
{"master", "enable master process manager"},
|
||||
{"help", "this help"},
|
||||
{"reaper", "process reaper (call waitpid(-1,...) after each request)"},
|
||||
{"max-requests", "maximum number of requests for each worker"},
|
||||
{"test", "test if uWSGI can import a module"},
|
||||
{"spooler <dir>", "run the spooler on directory <dir>"},
|
||||
{"pidfile <file>", "write the masterpid to <file>"},
|
||||
{"chroot <dir>", "chroot to directory <dir> (only root)"},
|
||||
{"gid <id/groupname>", "setgid to <id/groupname> (only root)"},
|
||||
{"uid <id/username>", "setuid to <id/username> (only root)"},
|
||||
{"chdir <dir>", "chdir to <dir> before app loading"},
|
||||
{"chdir2 <dir>", "chdir to <dir> after module loading"},
|
||||
{"no-server", "initialize the uWSGI server then exit. Useful for testing and using uwsgi embedded module"},
|
||||
{"no-defer-accept", "disable the no-standard way to defer the accept() call (TCP_DEFER_ACCEPT, SO_ACCEPTFILTER...)"},
|
||||
{"check-interval <sec>", "set the check interval (in seconds) of the master process"},
|
||||
{"limit-as <MB>", "limit the address space of processes to MB megabytes"},
|
||||
{"limit-post <bytes>", "limit HTTP content_length size to <bytes>"},
|
||||
{"post-buffering <bytes>", "buffer HTTP POST request higher than <bytes> to disk"},
|
||||
{"post-buffering-bufsize <b>", "set the buffer size to <b> bytes for post-buffering"},
|
||||
{"prio <N>", "set process priority/nice to N"},
|
||||
{"no-orphans", "automatically kill workers on master's dead"},
|
||||
{"udp <ip:port>", "bind master process to udp socket on ip:port"},
|
||||
{"multicast <group>", "set multicast group"},
|
||||
{"snmp", "enable SNMP support in the UDP server"},
|
||||
{"snmp-community <value>", "set SNMP community code to <value>"},
|
||||
{"erlang <name|address>", "enable the Erlang server with node name <name@address>"},
|
||||
{"erlang-cookie <cookie>", "set the erlang cookie to <cookie>"},
|
||||
{"nagios", "do a nagios check"},
|
||||
{"binary-path <bin-path>", "set the path for the next reload of uWSGI (needed for chroot environments)"},
|
||||
{"proxy <socket>", "run the uwsgi proxy on socket <socket>"},
|
||||
{"proxy-node <socket>", "add the node <socket> to the proxy"},
|
||||
{"proxy-max-connections <n>", "set the max number of concurrent connections mnaged by the proxy"},
|
||||
{"async <n>", "enable async mode with n core"},
|
||||
{"logto <logfile|addr>", "log to file/udp"},
|
||||
{"logdate", "add timestamp to loglines"},
|
||||
{"log-zero", "log requests with 0 response size"},
|
||||
{"log-slow <t>", "log requests slower than <t> milliseconds"},
|
||||
{"log-4xx", "log requests with status code 4xx"},
|
||||
{"log-5xx", "log requests with status code 5xx"},
|
||||
{"log-big <n>", "log requests bigger than <n> bytes"},
|
||||
{"log-sendfile", "log sendfile() requests"},
|
||||
{"ignore-script-name", "disable uWSGI management of SCRIPT_NAME"},
|
||||
{"no-default-app", "do not fallback unknown SCRIPT_NAME requests"},
|
||||
{"ini <inifile>", "path of ini config file"},
|
||||
{"ldap <url>", "url of LDAP uWSGIConfig resource"},
|
||||
{"ldap-schema", "dump uWSGIConfig LDAP schema"},
|
||||
{"ldap-schema-ldif", "dump uWSGIConfig LDAP schema in LDIF format"},
|
||||
{"grunt", "enable grunt workers"},
|
||||
{"ugreen", "enable uGreen support"},
|
||||
{"ugreen-stacksize <n>", "set uGreen stacksize to <n>"},
|
||||
{"no-site", "do not import site.py on startup"},
|
||||
{"vhost", "enable virtual hosting"},
|
||||
{"mount MOUNTPOINT=app", "add a new app under MOUNTPOINT"},
|
||||
{"routing", "enable uWSGI advanced routing"},
|
||||
{"http <addr>", "start embedded HTTP server on <addr>"},
|
||||
{"http-only", "start only the embedded HTTP server"},
|
||||
{"http-var KEY[=VALUE]", "add var KEY to uwsgi requests made by the embedded HTTP server"},
|
||||
{"catch-exceptions", "print exceptions in the browser"},
|
||||
{"mode", "set configuration mode"},
|
||||
{"env KEY=VALUE", "set environment variable"},
|
||||
{"vacuum", "clear the environment on exit (remove UNIX sockets and pidfiles)"},
|
||||
{"ping <addr>", "ping a uWSGI server (returns 1 on failure 0 on success)"},
|
||||
{"ping-timeout <n>", "set ping timeout to <n>"},
|
||||
{"cgroup <group>", "run the server in <group> cgroup (Linux only)"},
|
||||
{"cgroup-opt KEY=VAL", "set cgroup option (Linux only)"},
|
||||
{"version", "print server version"},
|
||||
{"daemonize <logfile|addr>", "daemonize and log into <logfile> or udp <addr>"},
|
||||
|
||||
{ 0, 0 },
|
||||
|
||||
};
|
||||
|
||||
|
||||
void uwsgi_help(void) {
|
||||
|
||||
struct uwsgi_help_item *uhi, *all_help;
|
||||
int max_size = 0;
|
||||
struct option *lopt;
|
||||
int found;
|
||||
char *space;
|
||||
char *tmp_option = NULL;
|
||||
int i;
|
||||
|
||||
all_help = main_help;
|
||||
|
||||
build_options();
|
||||
|
||||
while( (uhi = all_help) ) {
|
||||
|
||||
if (uhi->key == 0)
|
||||
break;
|
||||
|
||||
if ((int)strlen(uhi->key) > max_size) {
|
||||
max_size = (int)strlen(uhi->key);
|
||||
}
|
||||
|
||||
all_help++;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->help) {
|
||||
|
||||
all_help = uwsgi.p[i]->help;
|
||||
while( (uhi = all_help) ) {
|
||||
if (uhi->key == 0) break;
|
||||
if ((int)strlen(uhi->key) > max_size)
|
||||
max_size = (int)strlen(uhi->key);
|
||||
all_help++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->help) {
|
||||
|
||||
all_help = uwsgi.gp[i]->help ;
|
||||
while( (uhi = all_help) ) {
|
||||
if (uhi->key == 0) break;
|
||||
if ((int)strlen(uhi->key) > max_size)
|
||||
max_size = (int)strlen(uhi->key);
|
||||
all_help++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "Usage: %s [options...]\n", uwsgi.binary_path);
|
||||
|
||||
lopt = uwsgi.long_options;
|
||||
|
||||
max_size+=4;
|
||||
|
||||
while(lopt->name) {
|
||||
|
||||
found = 0;
|
||||
|
||||
all_help = main_help;
|
||||
while( (uhi = all_help) ) {
|
||||
if (uhi->key == 0) break;
|
||||
|
||||
tmp_option = uwsgi_concat2(uhi->key, "");
|
||||
space = strchr(tmp_option, ' ');
|
||||
if (space) space[0] = 0;
|
||||
|
||||
if (!strcmp(tmp_option, lopt->name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
free(tmp_option);
|
||||
all_help++;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
for (i = 0; i < 0xFF; i++) {
|
||||
if (uwsgi.p[i]->help) {
|
||||
all_help = uwsgi.p[i]->help;
|
||||
while( (uhi = all_help) ) {
|
||||
if (uhi->key == 0) break;
|
||||
tmp_option = uwsgi_concat2(uhi->key, "");
|
||||
space = strchr(tmp_option, ' ');
|
||||
if (space) space[0] = 0;
|
||||
|
||||
if (!strcmp(tmp_option, lopt->name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
free(tmp_option);
|
||||
all_help++;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
for (i = 0; i < uwsgi.gp_cnt; i++) {
|
||||
if (uwsgi.gp[i]->help) {
|
||||
all_help = uwsgi.gp[i]->help;
|
||||
while( (uhi = all_help) ) {
|
||||
if (uhi->key == 0) break;
|
||||
tmp_option = uwsgi_concat2(uhi->key, "");
|
||||
space = strchr(tmp_option, ' ');
|
||||
if (space) space[0] = 0;
|
||||
|
||||
if (!strcmp(tmp_option, lopt->name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
free(tmp_option);
|
||||
all_help++;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (found) {
|
||||
if (!lopt->flag && ( (lopt->val >= 'a' && lopt->val <= 'z') || (lopt->val >= 'A' && lopt->val <= 'Z'))) {
|
||||
fprintf(stdout, " -%c|--%-*s %s\n", lopt->val, max_size-3, uhi->key, uhi->value);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, " --%-*s %s\n", max_size, uhi->key, uhi->value);
|
||||
}
|
||||
if (tmp_option) free(tmp_option);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, " --%-*s *** UNDOCUMENTED OPTION ***\n", max_size, lopt->name);
|
||||
}
|
||||
|
||||
lopt++;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#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()")
|
||||
|
||||
@@ -98,6 +99,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>
|
||||
@@ -204,6 +209,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;
|
||||
@@ -357,7 +369,11 @@ 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 UWSGI_OK 0
|
||||
@@ -485,6 +501,8 @@ struct uwsgi_plugin {
|
||||
|
||||
uint16_t (*rpc)(void *, uint8_t, char **, char *);
|
||||
|
||||
struct uwsgi_help_item *help;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -554,6 +572,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;
|
||||
@@ -633,14 +658,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;
|
||||
@@ -652,6 +677,8 @@ struct wsgi_request {
|
||||
|
||||
int async_plagued;
|
||||
|
||||
int suspended;
|
||||
|
||||
int *ovector;
|
||||
size_t post_cl;
|
||||
char *post_buffering_buf;
|
||||
@@ -717,6 +744,8 @@ struct uwsgi_server {
|
||||
|
||||
time_t master_mercy;
|
||||
|
||||
int cpu_affinity;
|
||||
|
||||
int reload_mercy;
|
||||
int option_index;
|
||||
struct option *long_options;
|
||||
@@ -764,8 +793,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;
|
||||
@@ -794,13 +831,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
|
||||
|
||||
|
||||
@@ -830,14 +864,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;
|
||||
|
||||
@@ -943,6 +969,7 @@ struct uwsgi_server {
|
||||
|
||||
// usedby suspend/resume loops
|
||||
void (*schedule_to_main) (struct wsgi_request *);
|
||||
void (*schedule_to_req) (void);
|
||||
|
||||
int close_on_exec;
|
||||
|
||||
@@ -953,6 +980,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;
|
||||
|
||||
@@ -967,6 +996,9 @@ 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;
|
||||
@@ -1258,14 +1290,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
|
||||
@@ -1273,11 +1306,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
|
||||
@@ -1292,18 +1322,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);
|
||||
|
||||
@@ -1365,7 +1388,6 @@ int find_worker_id(pid_t);
|
||||
|
||||
|
||||
void *simple_loop(void *);
|
||||
void complex_loop(void);
|
||||
|
||||
int count_options(struct option *);
|
||||
|
||||
@@ -1435,7 +1457,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);
|
||||
@@ -1609,3 +1631,23 @@ 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);
|
||||
|
||||
+18
-4
@@ -71,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 += "\""
|
||||
@@ -93,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('/')
|
||||
|
||||
@@ -335,7 +342,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:
|
||||
@@ -377,9 +385,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")
|
||||
|
||||
Reference in New Issue
Block a user