mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b93dcbf46f | ||
|
|
8051a2bc98 | ||
|
|
78d8b221fc | ||
|
|
d51cada284 | ||
|
|
389eef9e88 | ||
|
|
270fb0c50d | ||
|
|
e7e9dfee88 | ||
|
|
3bafae276d | ||
|
|
cfebe2927d | ||
|
|
1d4294a845 | ||
|
|
12cfdd9864 | ||
|
|
add930c517 | ||
|
|
32972978be | ||
|
|
c8bad3550e | ||
|
|
ecc55d789d | ||
|
|
88555e2c20 | ||
|
|
ec2bfcd302 | ||
|
|
f1f81ed4c4 | ||
|
|
87933cca26 | ||
|
|
2dcd8624a2 | ||
|
|
7fcef76bbe | ||
|
|
2a5c4e938d | ||
|
|
274eae27ef | ||
|
|
207220bc50 | ||
|
|
fb8c4439c7 | ||
|
|
894be9c41e | ||
|
|
0a4bff8963 | ||
|
|
d515f3e279 |
@@ -1,5 +1,9 @@
|
||||
*.o
|
||||
*.py[co]
|
||||
*.class
|
||||
*.jar
|
||||
|
||||
/uwsgi
|
||||
/uwsgibuild.*
|
||||
|
||||
/t/ring/target
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
object file for embedded files will be put here
|
||||
+227
@@ -2,6 +2,233 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
#ifdef UWSGI_EVENT_USE_POLL
|
||||
#define UWSGI_EVENT_IN POLLIN
|
||||
#define UWSGI_EVENT_OUT POLLOUT
|
||||
|
||||
int uwsgi_poll_event_queue_max = 0;
|
||||
struct uwsgi_poll_event {
|
||||
int nevents;
|
||||
int max_events;
|
||||
pthread_mutex_t lock;
|
||||
struct pollfd *poll;
|
||||
};
|
||||
|
||||
struct uwsgi_poll_event **uwsgi_poll_event_queue;
|
||||
|
||||
// all of the public functions must be heavy locked
|
||||
|
||||
static int uwsgi_poll_fd_is_registered(struct uwsgi_poll_event *upe, int fd) {
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (upe->poll[i].fd == fd) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_poll_fd_add(struct uwsgi_poll_event *upe, int fd, int event) {
|
||||
int pos = upe->nevents;
|
||||
if (pos > upe->max_events) return -1;
|
||||
upe->poll[pos].fd = fd;
|
||||
upe->poll[pos].events = event;
|
||||
upe->nevents++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uwsgi_poll_fd_del(struct uwsgi_poll_event *upe, int fd) {
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (upe->poll[i].fd == fd) {
|
||||
if (i < upe->nevents-1) {
|
||||
memcpy(&upe->poll[i], &upe->poll[i+1], sizeof(struct uwsgi_poll_event) * (upe->nevents - (i+1)));
|
||||
}
|
||||
upe->nevents--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void uwsgi_poll_queue_rebuild(struct uwsgi_poll_event *upe) {
|
||||
// we need to check if some file descriptor is no more valid
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (!uwsgi_valid_fd(upe->poll[i].fd)) {
|
||||
uwsgi_poll_fd_del(upe, upe->poll[i].fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
uwsgi_poll_queue_rebuild(upe);
|
||||
int ret = poll(upe->poll, upe->nevents, timeout * 1000);
|
||||
if (ret > 0) {
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (upe->poll[i].revents) {
|
||||
*interesting_fd = upe->poll[i].fd;
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int event_queue_init() {
|
||||
if (!uwsgi_poll_event_queue) {
|
||||
uwsgi_poll_event_queue = uwsgi_calloc(sizeof(struct uwsgi_poll_event *) * uwsgi.max_fd);
|
||||
}
|
||||
int eq = uwsgi_poll_event_queue_max;
|
||||
uwsgi_poll_event_queue[eq] = uwsgi_calloc(sizeof(struct uwsgi_poll_event));
|
||||
uwsgi_poll_event_queue_max++;
|
||||
uwsgi_poll_event_queue[eq]->poll = uwsgi_malloc(sizeof(struct pollfd) * uwsgi.max_fd);
|
||||
uwsgi_poll_event_queue[eq]->max_events = uwsgi.max_fd;
|
||||
pthread_mutex_init(&uwsgi_poll_event_queue[eq]->lock, NULL);
|
||||
return eq;
|
||||
}
|
||||
|
||||
void *event_queue_alloc(int nevents) {
|
||||
return uwsgi_calloc(sizeof(struct pollfd) * nevents);
|
||||
}
|
||||
|
||||
int event_queue_interesting_fd_is_read(void *events, int id) {
|
||||
struct pollfd *pevents = (struct pollfd *)events;
|
||||
struct pollfd *upoll = &pevents[id];
|
||||
if (upoll->revents & POLLIN) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_queue_fd_write_to_readwrite(int eq, int fd) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (upe->poll[i].fd == fd) {
|
||||
upe->poll[i].events = POLLIN|POLLOUT;
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int event_queue_fd_read_to_readwrite(int eq, int fd) {
|
||||
return event_queue_fd_write_to_readwrite(eq, fd);
|
||||
}
|
||||
|
||||
int event_queue_interesting_fd_is_write(void *events, int id) {
|
||||
struct pollfd *pevents = (struct pollfd *)events;
|
||||
struct pollfd *upoll = &pevents[id];
|
||||
if (upoll->revents & POLLOUT) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_queue_add_fd_read(int eq, int fd) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
if (uwsgi_poll_fd_is_registered(upe, fd)) {
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return 0;
|
||||
}
|
||||
int ret = uwsgi_poll_fd_add(upe, fd, POLLIN);
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return ret;
|
||||
}
|
||||
int event_queue_add_fd_write(int eq, int fd) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
if (uwsgi_poll_fd_is_registered(upe, fd)) {
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return 0;
|
||||
}
|
||||
int ret = uwsgi_poll_fd_add(upe, fd, POLLOUT);
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return ret;
|
||||
}
|
||||
int event_queue_del_fd(int eq, int fd, int event) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
int ret = uwsgi_poll_fd_del(upe, fd);
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return ret;
|
||||
}
|
||||
int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
uwsgi_poll_queue_rebuild(upe);
|
||||
int ret = poll(upe->poll, upe->nevents, timeout * 1000);
|
||||
int cnt = 0;
|
||||
if (ret > 0) {
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (upe->poll[i].revents) {
|
||||
struct pollfd *pevents = (struct pollfd *)events;
|
||||
struct pollfd *upoll = &pevents[cnt];
|
||||
upoll->fd = upe->poll[i].fd;
|
||||
upoll->revents = upe->poll[i].revents;
|
||||
upoll->events = upe->poll[i].events;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
if (ret <= 0) return ret;
|
||||
return cnt;
|
||||
}
|
||||
int event_queue_interesting_fd_has_error(void *events, int id) {
|
||||
struct pollfd *pevents = (struct pollfd *)events;
|
||||
struct pollfd *upoll = &pevents[id];
|
||||
if (upoll->revents & POLLERR || upoll->revents & POLLHUP || upoll->revents & POLLNVAL) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int event_queue_interesting_fd(void *events, int id) {
|
||||
struct pollfd *pevents = (struct pollfd *)events;
|
||||
struct pollfd *upoll = &pevents[id];
|
||||
return upoll->fd;
|
||||
}
|
||||
int event_queue_fd_write_to_read(int eq, int fd) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (upe->poll[i].fd == fd) {
|
||||
upe->poll[i].events = POLLIN;
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return -1;
|
||||
}
|
||||
int event_queue_fd_read_to_write(int eq, int fd) {
|
||||
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
||||
pthread_mutex_lock(&upe->lock);
|
||||
int i;
|
||||
for(i=0;i<upe->nevents;i++) {
|
||||
if (upe->poll[i].fd == fd) {
|
||||
upe->poll[i].events = POLLOUT;
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&upe->lock);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UWSGI_EVENT_USE_PORT
|
||||
|
||||
#include <port.h>
|
||||
|
||||
@@ -770,10 +770,10 @@ timeout:
|
||||
// check if an fd is valid
|
||||
int uwsgi_valid_fd(int fd) {
|
||||
int ret = fcntl(fd, F_GETFL);
|
||||
if (ret == 0) {
|
||||
return 1;
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uwsgi_close_all_fds(void) {
|
||||
|
||||
+54
@@ -401,6 +401,60 @@ void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_unlock_fast(uli);
|
||||
}
|
||||
|
||||
#elif defined(UWSGI_LOCK_USE_WINDOWS_MUTEX)
|
||||
|
||||
#define UWSGI_LOCK_ENGINE_NAME "windows mutexes"
|
||||
#define UWSGI_LOCK_SIZE sizeof(HANDLE)
|
||||
#define UWSGI_RWLOCK_SIZE sizeof(HANDLE)
|
||||
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
|
||||
|
||||
struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0);
|
||||
struct _SECURITY_ATTRIBUTES sa;
|
||||
memset(&sa, 0, sizeof(struct _SECURITY_ATTRIBUTES));
|
||||
sa.bInheritHandle = 1;
|
||||
uli->lock_ptr = CreateMutex(&sa, FALSE, NULL);
|
||||
return uli;
|
||||
}
|
||||
|
||||
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
|
||||
WaitForSingleObject(uli->lock_ptr, INFINITE);
|
||||
uli->pid = uwsgi.mypid;
|
||||
}
|
||||
|
||||
void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) {
|
||||
ReleaseMutex(uli->lock_ptr);
|
||||
uli->pid = 0;
|
||||
}
|
||||
|
||||
pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
if (WaitForSingleObject(uli->lock_ptr, 0) == WAIT_TIMEOUT) {
|
||||
return 0;
|
||||
}
|
||||
return uli->pid;
|
||||
}
|
||||
|
||||
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) {
|
||||
return uwsgi_lock_fast_init(id);
|
||||
}
|
||||
|
||||
void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_lock_fast(uli);
|
||||
}
|
||||
|
||||
pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) {
|
||||
return uwsgi_lock_fast_check(uli);
|
||||
}
|
||||
|
||||
void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
|
||||
uwsgi_unlock_fast(uli);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define uwsgi_lock_fast_init uwsgi_lock_ipcsem_init
|
||||
|
||||
+26
-5
@@ -1,9 +1,9 @@
|
||||
#define _NO_UWSGI_RB
|
||||
#include "uwsgi.h"
|
||||
|
||||
#ifndef __DragonFly__
|
||||
#include <uwsgi.h>
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
||||
#include <kvm.h>
|
||||
#include <sys/user.h>
|
||||
#include <kvm.h>
|
||||
#elif defined(__sun__)
|
||||
/* Terrible Hack !!! */
|
||||
#ifndef _LP64
|
||||
@@ -17,6 +17,10 @@
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef __DragonFly__
|
||||
#include <uwsgi.h>
|
||||
#endif
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
//use this instead of fprintf to avoid buffering mess with udp logging
|
||||
@@ -314,7 +318,7 @@ static struct uwsgi_logger *setup_choosen_logger(struct uwsgi_string_list *usl)
|
||||
int is_id = 1;
|
||||
int i;
|
||||
for (i = 0; i < (space - name); i++) {
|
||||
if (!isalnum(name[i])) {
|
||||
if (!isalnum((int)name[i])) {
|
||||
is_id = 0;
|
||||
break;
|
||||
}
|
||||
@@ -686,6 +690,18 @@ void get_memusage(uint64_t * rss, uint64_t * vsz) {
|
||||
fclose(procfile);
|
||||
}
|
||||
*rss = *rss * uwsgi.page_size;
|
||||
#elif defined(__CYGWIN__)
|
||||
// same as Linux but rss is not in pages...
|
||||
FILE *procfile;
|
||||
int i;
|
||||
procfile = fopen("/proc/self/stat", "r");
|
||||
if (procfile) {
|
||||
i = fscanf(procfile, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %llu %lld", (unsigned long long *) vsz, (unsigned long long *) rss);
|
||||
if (i != 2) {
|
||||
uwsgi_log("warning: invalid record in /proc/self/stat\n");
|
||||
}
|
||||
fclose(procfile);
|
||||
}
|
||||
#elif defined (__sun__)
|
||||
psinfo_t info;
|
||||
int procfd;
|
||||
@@ -725,8 +741,13 @@ void get_memusage(uint64_t * rss, uint64_t * vsz) {
|
||||
struct kinfo_proc *kproc;
|
||||
kproc = kvm_getprocs(kv, KERN_PROC_PID, uwsgi.mypid, &cnt);
|
||||
if (kproc && cnt > 0) {
|
||||
#if defined(__FreeBSD__)
|
||||
*vsz = kproc->ki_size;
|
||||
*rss = kproc->ki_rssize * uwsgi.page_size;
|
||||
#elif defined(__DragonFly__)
|
||||
*vsz = kproc->kp_vm_map_size;
|
||||
*rss = kproc->kp_vm_rssize * uwsgi.page_size;
|
||||
#endif
|
||||
}
|
||||
#elif defined(UWSGI_NEW_OPENBSD)
|
||||
struct kinfo_proc *kproc;
|
||||
|
||||
@@ -961,9 +961,24 @@ int uwsgi_hooked_parse_array(char *buffer, size_t len, void (*hook) (uint16_t, c
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
the following functions need to take in account that POST data could be already available in wsgi_req->buffer (generally when uwsgi protocol is in use)
|
||||
|
||||
In such a case, allocate a proto_parser_buf and move data there
|
||||
|
||||
*/
|
||||
|
||||
char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, char *val, uint16_t vallen) {
|
||||
|
||||
if (!wsgi_req->proto_parser_buf) {
|
||||
if (wsgi_req->proto_parser_remains > 0) {
|
||||
wsgi_req->proto_parser_buf = uwsgi_malloc(wsgi_req->proto_parser_remains);
|
||||
memcpy(wsgi_req->proto_parser_buf, wsgi_req->proto_parser_remains_buf, wsgi_req->proto_parser_remains);
|
||||
wsgi_req->proto_parser_remains_buf = wsgi_req->proto_parser_buf;
|
||||
}
|
||||
}
|
||||
|
||||
if ((wsgi_req->uh->pktsize + (2 + keylen + 2 + vallen)) > uwsgi.buffer_size) {
|
||||
uwsgi_log("not enough buffer space to add %.*s variable, consider increasing it with the --buffer-size option\n", keylen, key);
|
||||
return NULL;
|
||||
@@ -1001,6 +1016,15 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen
|
||||
}
|
||||
|
||||
int uwsgi_req_append_path_info_with_index(struct wsgi_request *wsgi_req, char *index, uint16_t index_len) {
|
||||
|
||||
if (!wsgi_req->proto_parser_buf) {
|
||||
if (wsgi_req->proto_parser_remains > 0) {
|
||||
wsgi_req->proto_parser_buf = uwsgi_malloc(wsgi_req->proto_parser_remains);
|
||||
memcpy(wsgi_req->proto_parser_buf, wsgi_req->proto_parser_remains_buf, wsgi_req->proto_parser_remains);
|
||||
wsgi_req->proto_parser_remains_buf = wsgi_req->proto_parser_buf;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t need_slash = 0;
|
||||
if (wsgi_req->path_info_len > 0) {
|
||||
if (wsgi_req->path_info[wsgi_req->path_info_len-1] != '/') {
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ int uwsgi_apply_routes(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
|
||||
// in case ogf static files serving previous rules could be applied
|
||||
// in case of static files serving previous rules could be applied
|
||||
if (wsgi_req->routes_applied) {
|
||||
return UWSGI_ROUTE_CONTINUE;
|
||||
}
|
||||
|
||||
+18
-1
@@ -2,6 +2,23 @@
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
static int uwsgi_socket_strcmp(char *sock1, char *sock2) {
|
||||
size_t sock1_len = strlen(sock1);
|
||||
size_t sock2_len = strlen(sock2);
|
||||
|
||||
if (!uwsgi_starts_with(sock1, sock1_len, "0.0.0.0:", 8)) {
|
||||
sock1 += 7;
|
||||
sock1_len = strlen(sock1);
|
||||
}
|
||||
|
||||
if (!uwsgi_starts_with(sock2, sock2_len, "0.0.0.0:", 8)) {
|
||||
sock2 += 7;
|
||||
sock2_len = strlen(sock2);
|
||||
}
|
||||
|
||||
return uwsgi_strncmp(sock1, sock1_len, sock2, sock2_len);
|
||||
}
|
||||
|
||||
char *uwsgi_getsockname(int fd) {
|
||||
|
||||
socklen_t socket_type_len = sizeof(struct sockaddr_un);
|
||||
@@ -1476,7 +1493,7 @@ void uwsgi_setup_shared_sockets() {
|
||||
for (i = 3; i < (int) uwsgi.max_fd; i++) {
|
||||
char *sock = uwsgi_getsockname(i);
|
||||
if (sock) {
|
||||
if (!strcmp(sock, shared_sock->name)) {
|
||||
if (!uwsgi_socket_strcmp(sock, shared_sock->name)) {
|
||||
if (strchr(sock, ':')) {
|
||||
uwsgi_log("uwsgi shared socket %d inherited TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), sock, i);
|
||||
shared_sock->family = AF_INET;
|
||||
|
||||
+1
-1
@@ -609,7 +609,7 @@ safe:
|
||||
|
||||
#ifdef UWSGI_ROUTING
|
||||
// before sending the file, we need to check if some rule applies
|
||||
if (uwsgi_apply_routes_do(wsgi_req, NULL, 0) == UWSGI_ROUTE_BREAK) {
|
||||
if (!wsgi_req->is_routing && uwsgi_apply_routes_do(wsgi_req, NULL, 0) == UWSGI_ROUTE_BREAK) {
|
||||
return 0;
|
||||
}
|
||||
wsgi_req->routes_applied = 1;
|
||||
|
||||
+2
-1
@@ -383,7 +383,8 @@ struct uwsgi_stats_pusher_instance *uwsgi_stats_pusher_add(struct uwsgi_stats_pu
|
||||
|
||||
uspi = uwsgi_calloc(sizeof(struct uwsgi_stats_pusher_instance));
|
||||
uspi->pusher = pusher;
|
||||
uspi->arg = arg;
|
||||
uspi->arg = uwsgi_str(arg);
|
||||
uspi->raw = pusher->raw;
|
||||
if (old_uspi) {
|
||||
old_uspi->next = uspi;
|
||||
}
|
||||
|
||||
+9
-1
@@ -2470,13 +2470,19 @@ void uwsgi_chown(char *filename, char *owner) {
|
||||
|
||||
char *uwsgi_get_binary_path(char *argvzero) {
|
||||
|
||||
#if defined(__linux__)
|
||||
#if defined(__linux__) || defined(__CYGWIN__)
|
||||
char *buf = uwsgi_calloc(PATH_MAX + 1);
|
||||
ssize_t len = readlink("/proc/self/exe", buf, PATH_MAX);
|
||||
if (len > 0) {
|
||||
return buf;
|
||||
}
|
||||
free(buf);
|
||||
#elif defined(_WIN32)
|
||||
char *buf = uwsgi_calloc(PATH_MAX + 1);
|
||||
if (GetModuleFileName(NULL, buf, PATH_MAX) > 0) {
|
||||
return buf;
|
||||
}
|
||||
free(buf);
|
||||
#elif defined(__NetBSD__)
|
||||
char *buf = uwsgi_calloc(PATH_MAX + 1);
|
||||
ssize_t len = readlink("/proc/curproc/exe", buf, PATH_MAX);
|
||||
@@ -2941,11 +2947,13 @@ pid_t uwsgi_fork(char *name) {
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
if (uwsgi.never_swap) {
|
||||
if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
|
||||
uwsgi_error("mlockall()");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__sun__)
|
||||
int i;
|
||||
|
||||
+18
-3
@@ -976,9 +976,18 @@ void grace_them_all(int signum) {
|
||||
if (uwsgi_instance_is_reloading || uwsgi_instance_is_dying)
|
||||
return;
|
||||
|
||||
int i;
|
||||
|
||||
if (uwsgi.lazy) {
|
||||
for (i = 1; i <= uwsgi.numproc; i++) {
|
||||
uwsgi_curse(i, SIGHUP);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uwsgi.status.gracefully_reloading = 1;
|
||||
|
||||
int i;
|
||||
int waitpid_status;
|
||||
|
||||
|
||||
@@ -1011,8 +1020,6 @@ void grace_them_all(int signum) {
|
||||
}
|
||||
}
|
||||
else if (uwsgi.workers[i].pid > 0) {
|
||||
if (uwsgi.lazy)
|
||||
uwsgi.workers[i].destroy = 1;
|
||||
uwsgi_curse(i, SIGHUP);
|
||||
}
|
||||
}
|
||||
@@ -1701,7 +1708,13 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
// count/set the current reload status
|
||||
uwsgi_setup_reload();
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
uwsgi.page_size = si.dwPageSize;
|
||||
#else
|
||||
uwsgi.page_size = getpagesize();
|
||||
#endif
|
||||
uwsgi.binary_path = uwsgi_get_binary_path(argv[0]);
|
||||
|
||||
// ok we can now safely play with argv and environ
|
||||
@@ -1785,12 +1798,14 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||
// initial log setup (files and daemonization)
|
||||
uwsgi_setup_log();
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
// enable never-swap mode
|
||||
if (uwsgi.never_swap) {
|
||||
if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
|
||||
uwsgi_error("mlockall()");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uwsgi.flock2)
|
||||
uwsgi_opt_flock(NULL, uwsgi.flock2, NULL);
|
||||
|
||||
+11
-1
@@ -18,6 +18,7 @@ static void uwsgi_opt_setup_gevent(char *opt, char *value, void *null) {
|
||||
|
||||
static struct uwsgi_option gevent_options[] = {
|
||||
{"gevent", required_argument, 0, "a shortcut enabling gevent loop engine with the specified number of async cores and optimal parameters", uwsgi_opt_setup_gevent, NULL, UWSGI_OPT_THREADS},
|
||||
{"gevent-monkey-patch", no_argument, 0, "call gevent.monkey.patch_all() automatically on startup", uwsgi_opt_true, &ugevent.monkey, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
};
|
||||
@@ -317,6 +318,16 @@ static void gevent_loop() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// call gevent.monkey.patch_all() if requested
|
||||
if (ugevent.monkey) {
|
||||
PyObject *gevent_monkey_dict = get_uwsgi_pydict("gevent.monkey");
|
||||
if (!gevent_monkey_dict) uwsgi_pyexit;
|
||||
PyObject *gevent_monkey_patch_all = PyDict_GetItemString(gevent_monkey_dict, "patch_all");
|
||||
if (!gevent_monkey_patch_all) uwsgi_pyexit;
|
||||
PyObject *ret = python_call(gevent_monkey_patch_all, PyTuple_New(0), 0, NULL);
|
||||
if (!ret) uwsgi_pyexit;
|
||||
}
|
||||
|
||||
ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
|
||||
if (!ugevent.spawn) uwsgi_pyexit;
|
||||
|
||||
@@ -329,7 +340,6 @@ static void gevent_loop() {
|
||||
ugevent.greenlet_switch_args = PyTuple_New(0);
|
||||
Py_INCREF(ugevent.greenlet_switch_args);
|
||||
|
||||
|
||||
PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");
|
||||
|
||||
ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
|
||||
|
||||
@@ -52,5 +52,6 @@ struct uwsgi_gevent {
|
||||
PyObject *signal_watcher;
|
||||
PyObject **watchers;
|
||||
int destroy;
|
||||
int monkey;
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -587,6 +587,8 @@ ssize_t http_parse(struct corerouter_peer *main_peer) {
|
||||
size_t len = main_peer->in->pos;
|
||||
char *ptr = main_peer->in->buf;
|
||||
|
||||
hr->rnrn = 0;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
if (*ptr == '\r' && (hr->rnrn == 0 || hr->rnrn == 2)) {
|
||||
hr->rnrn++;
|
||||
@@ -770,8 +772,6 @@ int http_alloc_session(struct uwsgi_corerouter *ucr, struct uwsgi_gateway_socket
|
||||
|
||||
}
|
||||
|
||||
hr->rnrn = 0;
|
||||
|
||||
hr->port = ugs->port;
|
||||
hr->port_len = ugs->port_len;
|
||||
switch(ugs->mode) {
|
||||
|
||||
@@ -108,3 +108,5 @@ int uwsgi_jvm_object_to_response_body(struct wsgi_request *, jobject);
|
||||
jobject uwsgi_jvm_bytearray(char *, size_t);
|
||||
char *uwsgi_jvm_bytearray2c(jobject);
|
||||
void uwsgi_jvm_release_bytearray(jobject, char *);
|
||||
|
||||
jobject uwsgi_jvm_to_string(jobject);
|
||||
|
||||
@@ -243,6 +243,15 @@ jobject uwsgi_jvm_entryset(jobject o) {
|
||||
return uwsgi_jvm_call_object(o, mid);
|
||||
}
|
||||
|
||||
jobject uwsgi_jvm_to_string(jobject o) {
|
||||
jclass c = uwsgi_jvm_class_from_object(o);
|
||||
if (!c) return NULL;
|
||||
jmethodID mid = uwsgi_jvm_get_method_id_quiet(c, "toString", "()Ljava/lang/String;");
|
||||
uwsgi_jvm_local_unref(c);
|
||||
if (!mid) return NULL;
|
||||
return uwsgi_jvm_call_object(o, mid);
|
||||
}
|
||||
|
||||
int uwsgi_jvm_object_to_response_body(struct wsgi_request *wsgi_req, jobject body) {
|
||||
|
||||
// check for string
|
||||
@@ -297,20 +306,35 @@ int uwsgi_jvm_object_to_response_body(struct wsgi_request *wsgi_req, jobject bod
|
||||
ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_chars(chunk, c_body);
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
if (ret) goto done;
|
||||
continue;
|
||||
}
|
||||
else if (uwsgi_jvm_object_is_instance(chunk, ujvm.bytearray_class)) {
|
||||
|
||||
if (uwsgi_jvm_object_is_instance(chunk, ujvm.bytearray_class)) {
|
||||
char *c_body = uwsgi_jvm_bytearray2c(chunk);
|
||||
size_t c_body_len = uwsgi_jvm_array_len(chunk);
|
||||
ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_bytearray(chunk, c_body);
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
if (ret) goto done;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
uwsgi_log("body iterable item must be java/lang/String or array of bytes!!!\n");
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
goto done;
|
||||
|
||||
jobject str_o = uwsgi_jvm_to_string(chunk);
|
||||
if (str_o) {
|
||||
char *c_body = uwsgi_jvm_str2c(str_o);
|
||||
size_t c_body_len = uwsgi_jvm_strlen(str_o);
|
||||
ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
|
||||
uwsgi_jvm_release_chars(str_o, c_body);
|
||||
uwsgi_jvm_local_unref(str_o);
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
if (ret) goto done;
|
||||
continue;
|
||||
}
|
||||
if (ret) goto done;
|
||||
|
||||
uwsgi_log("body iterable item must be java/lang/String or array of bytes!!!\n");
|
||||
uwsgi_jvm_local_unref(chunk);
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
uwsgi_jvm_local_unref(chunks);
|
||||
@@ -592,11 +616,10 @@ int uwsgi_jvm_consume_input_stream(struct wsgi_request *wsgi_req, size_t chunk,
|
||||
break;
|
||||
}
|
||||
// get the body of the array
|
||||
size_t buf_len = uwsgi_jvm_array_len(byte_buffer);
|
||||
char *buf = (char *) (*ujvm_env)->GetByteArrayElements(ujvm_env, byte_buffer, JNI_FALSE);
|
||||
if (!buf) { ret = -1; break; }
|
||||
//send
|
||||
if (uwsgi_response_write_body_do(wsgi_req, buf, buf_len)) {
|
||||
if (uwsgi_response_write_body_do(wsgi_req, buf, len)) {
|
||||
(*ujvm_env)->ReleaseByteArrayElements(ujvm_env, byte_buffer, (jbyte *) buf, 0);
|
||||
ret = -1; break;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ if operating_system == 'darwin':
|
||||
if os.path.exists(jvm):
|
||||
JVM_INCPATH = ["-Wno-deprecated-declarations", "-I%s" % jvm]
|
||||
JVM_LIBPATH = ["-framework JavaVM"]
|
||||
elif operating_system.startswith('cygwin'):
|
||||
JVM_INCPATH = ['-I"/cygdrive/c/Program Files/Java/jdk1.7.0_17/include"', '-I"/cygdrive/c/Program Files/Java/jdk1.7.0_17/include/win32"']
|
||||
JVM_LIBPATH = ['-L"/cygdrive/c/Program Files/Java/jdk1.7.0_17/jre/bin/server"']
|
||||
else:
|
||||
known_jvms = ('/usr/lib/jvm/java-7-openjdk', '/usr/local/openjdk7', '/usr/lib/jvm/java-6-openjdk', '/usr/local/openjdk', '/usr/java', '/usr/lib/jvm/java/')
|
||||
for jvm in known_jvms:
|
||||
@@ -34,12 +37,12 @@ else:
|
||||
break
|
||||
|
||||
try:
|
||||
JVM_INCPATH = os.environ['UWSGICONFIG_JVM_INCPATH']
|
||||
JVM_INCPATH = ['-I"' + os.environ['UWSGICONFIG_JVM_INCPATH'] + '"']
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
JVM_LIBPATH = os.environ['UWSGICONFIG_JVM_LIBPATH']
|
||||
JVM_LIBPATH = ['-L"' + os.environ['UWSGICONFIG_JVM_LIBPATH'] + '"']
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@@ -126,8 +126,10 @@ struct uwsgi_option uwsgi_python_options[] = {
|
||||
{"ini-paste-logged", required_argument, 0, "load a paste.deploy config file containing uwsgi section (load loggers too)", uwsgi_opt_ini_paste, NULL, UWSGI_OPT_IMMEDIATE},
|
||||
#endif
|
||||
{"reload-os-env", no_argument, 0, "force reload of os.environ at each request", uwsgi_opt_true, &up.reload_os_env, 0},
|
||||
#ifndef __CYGWIN__
|
||||
#ifndef UWSGI_PYPY
|
||||
{"no-site", no_argument, 0, "do not import site module", uwsgi_opt_true, &Py_NoSiteFlag, 0},
|
||||
#endif
|
||||
#endif
|
||||
{"pyshell", no_argument, 0, "run an interactive python shell in the uWSGI environment", uwsgi_opt_pyshell, NULL, 0},
|
||||
{"pyshell-oneshot", no_argument, 0, "run an interactive python shell in the uWSGI environment (one-shot variant)", uwsgi_opt_pyshell, NULL, 0},
|
||||
|
||||
@@ -244,7 +244,7 @@ static int uwsgi_ring_request(struct wsgi_request *wsgi_req) {
|
||||
// *** REQUEST GENERATION ***
|
||||
|
||||
if (uwsgi_ring_request_item_add_keyword(hm, "request-method", 14, wsgi_req->method, wsgi_req->method_len)) goto end;
|
||||
if (uwsgi_ring_request_item_add(hm, "uri", 3, wsgi_req->uri, wsgi_req->uri_len)) goto end;
|
||||
if (uwsgi_ring_request_item_add(hm, "uri", 3, wsgi_req->path_info, wsgi_req->path_info_len)) goto end;
|
||||
if (uwsgi_ring_request_item_add(hm, "server-name", 11, wsgi_req->host, wsgi_req->host_len)) goto end;
|
||||
|
||||
// server-port is required !!!
|
||||
@@ -450,10 +450,13 @@ static int uwsgi_ring_setup() {
|
||||
}
|
||||
|
||||
char *namespace = uwsgi_str(uring.app);
|
||||
char *colon = strchr(namespace, ':');
|
||||
char *colon = strchr(namespace, '/');
|
||||
if (!colon) {
|
||||
uwsgi_log("invalid ring application namespace/handler\n");
|
||||
exit(1);
|
||||
colon = strchr(namespace, ':');
|
||||
if (!colon) {
|
||||
uwsgi_log("invalid ring application namespace/handler\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
*colon = 0;
|
||||
uring.handler = uwsgi_jvm_call_object_static(clojure, clojure_var, uwsgi_jvm_str(namespace, 0), uwsgi_jvm_str(colon+1, 0));
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
#ifdef __linux__
|
||||
#include <crypt.h>
|
||||
#elif defined(__CYGWIN__)
|
||||
#include <crypt.h>
|
||||
pthread_mutex_t ur_basicauth_crypt_mutex;
|
||||
#else
|
||||
pthread_mutex_t ur_basicauth_crypt_mutex;
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <uwsgi.h>
|
||||
|
||||
void stats_pusher_mongodb(struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../../uwsgi.h"
|
||||
#include <uwsgi.h>
|
||||
|
||||
#include "client/dbclient.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
#include <uwsgi.h>
|
||||
|
||||
/*
|
||||
|
||||
this is a stats pusher plugin for the statsd server:
|
||||
|
||||
--stats-push statsd:address[,prefix]
|
||||
|
||||
example:
|
||||
|
||||
--stats-push statsd:127.0.0.1:8125,myinstance
|
||||
|
||||
it is pretty minimal, but will be extended after the 2.0 metric subsystem will be released
|
||||
|
||||
*/
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
// configuration of a statsd node
|
||||
struct statsd_node {
|
||||
int fd;
|
||||
union uwsgi_sockaddr addr;
|
||||
socklen_t addr_len;
|
||||
char *prefix;
|
||||
uint16_t prefix_len;
|
||||
};
|
||||
|
||||
static int statsd_send_worker_gauge(struct uwsgi_buffer *ub, struct uwsgi_stats_pusher_instance *uspi, int wid, char *metric, uint16_t metric_len, int64_t value) {
|
||||
struct statsd_node *sn = (struct statsd_node *) uspi->data;
|
||||
// reset the buffer
|
||||
ub->pos = 0;
|
||||
if (uwsgi_buffer_append(ub, sn->prefix, sn->prefix_len)) return -1;
|
||||
if (uwsgi_buffer_append(ub, ".worker", 7)) return -1;
|
||||
if (uwsgi_buffer_num64(ub, wid)) return -1;
|
||||
if (uwsgi_buffer_append(ub, ".", 1)) return -1;
|
||||
if (uwsgi_buffer_append(ub, metric, metric_len)) return -1;
|
||||
if (uwsgi_buffer_append(ub, ":", 1)) return -1;
|
||||
if (uwsgi_buffer_num64(ub, value)) return -1;
|
||||
if (uwsgi_buffer_append(ub, "|g", 2)) return -1;
|
||||
|
||||
if (sendto(sn->fd, ub->buf, ub->pos, 0, (struct sockaddr *) &sn->addr.sa_in, sn->addr_len) < 0) {
|
||||
uwsgi_error("stats_pusher_statsd()/sendto()");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int statsd_send_core_gauge(struct uwsgi_buffer *ub, struct uwsgi_stats_pusher_instance *uspi, int wid, int coreid, char *metric, uint16_t metric_len, int64_t value) {
|
||||
struct statsd_node *sn = (struct statsd_node *) uspi->data;
|
||||
// reset the buffer
|
||||
ub->pos = 0;
|
||||
if (uwsgi_buffer_append(ub, sn->prefix, sn->prefix_len)) return -1;
|
||||
if (uwsgi_buffer_append(ub, ".worker", 7)) return -1;
|
||||
if (uwsgi_buffer_num64(ub, wid)) return -1;
|
||||
if (uwsgi_buffer_append(ub, ".core", 5)) return -1;
|
||||
if (uwsgi_buffer_num64(ub, coreid)) return -1;
|
||||
if (uwsgi_buffer_append(ub, ".", 1)) return -1;
|
||||
if (uwsgi_buffer_append(ub, metric, metric_len)) return -1;
|
||||
if (uwsgi_buffer_append(ub, ":", 1)) return -1;
|
||||
if (uwsgi_buffer_num64(ub, value)) return -1;
|
||||
if (uwsgi_buffer_append(ub, "|g", 2)) return -1;
|
||||
|
||||
if (sendto(sn->fd, ub->buf, ub->pos, 0, (struct sockaddr *) &sn->addr.sa_in, sn->addr_len) < 0) {
|
||||
uwsgi_error("stats_pusher_statsd()/sendto()");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void stats_pusher_statsd(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
|
||||
|
||||
if (!uspi->configured) {
|
||||
struct statsd_node *sn = uwsgi_calloc(sizeof(struct statsd_node));
|
||||
char *comma = strchr(uspi->arg, ',');
|
||||
if (comma) {
|
||||
sn->prefix = comma+1;
|
||||
sn->prefix_len = strlen(sn->prefix);
|
||||
*comma = 0;
|
||||
}
|
||||
else {
|
||||
sn->prefix = "uwsgi";
|
||||
sn->prefix_len = 5;
|
||||
}
|
||||
|
||||
char *colon = strchr(uspi->arg, ':');
|
||||
if (!colon) {
|
||||
uwsgi_log("invalid statsd address %s\n", uspi->arg);
|
||||
if (comma) *comma = ',';
|
||||
free(sn);
|
||||
return;
|
||||
}
|
||||
sn->addr_len = socket_to_in_addr(uspi->arg, colon, 0, &sn->addr.sa_in);
|
||||
|
||||
sn->fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sn->fd < 0) {
|
||||
uwsgi_error("stats_pusher_statsd()/socket()");
|
||||
if (comma) *comma = ',';
|
||||
free(sn);
|
||||
return;
|
||||
}
|
||||
uwsgi_socket_nb(sn->fd);
|
||||
if (comma) *comma = ',';
|
||||
uspi->data = sn;
|
||||
uspi->configured = 1;
|
||||
}
|
||||
|
||||
// we use the same buffer for all of the packets
|
||||
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
|
||||
|
||||
int i, j;
|
||||
// send workers metrics
|
||||
for(i=1;i<=uwsgi.numproc;i++) {
|
||||
if (statsd_send_worker_gauge(ub, uspi, i, "requests", 8, uwsgi.workers[i].requests)) goto end;
|
||||
for(j=0;j<uwsgi.cores;j++) {
|
||||
if (statsd_send_core_gauge(ub, uspi, i, j, "exceptions", 10, uwsgi.workers[i].cores[j].exceptions)) goto end;
|
||||
if (statsd_send_core_gauge(ub, uspi, i, j, "requests", 8, uwsgi.workers[i].cores[j].requests)) goto end;
|
||||
if (statsd_send_core_gauge(ub, uspi, i, j, "routed_requests", 15, uwsgi.workers[i].cores[j].routed_requests)) goto end;
|
||||
if (statsd_send_core_gauge(ub, uspi, i, j, "static_requests", 15, uwsgi.workers[i].cores[j].static_requests)) goto end;
|
||||
if (statsd_send_core_gauge(ub, uspi, i, j, "offloaded_requests", 18, uwsgi.workers[i].cores[j].offloaded_requests)) goto end;
|
||||
}
|
||||
}
|
||||
end:
|
||||
uwsgi_buffer_destroy(ub);
|
||||
}
|
||||
|
||||
static void stats_pusher_statsd_init(void) {
|
||||
struct uwsgi_stats_pusher *usp = uwsgi_register_stats_pusher("statsd", stats_pusher_statsd);
|
||||
// we use a custom format not the JSON one
|
||||
usp->raw = 1;
|
||||
}
|
||||
|
||||
struct uwsgi_plugin stats_pusher_statsd_plugin = {
|
||||
|
||||
.name = "stats_pusher_statsd",
|
||||
.on_load = stats_pusher_statsd_init,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
NAME='stats_pusher_statsd'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['plugin']
|
||||
+203
-194
@@ -1,32 +1,37 @@
|
||||
#include "../uwsgi.h"
|
||||
/*
|
||||
|
||||
generic ZeroMQ functions + Mongrel2 protocol parser
|
||||
|
||||
*/
|
||||
#include <uwsgi.h>
|
||||
|
||||
extern struct uwsgi_server uwsgi;
|
||||
|
||||
void *uwsgi_zeromq_init() {
|
||||
if (!uwsgi.zmq_context) {
|
||||
uwsgi.zmq_context = zmq_init(1);
|
||||
if (uwsgi.zmq_context == NULL) {
|
||||
uwsgi_error("zmq_init()");
|
||||
exit(1);
|
||||
}
|
||||
if (uwsgi.zmq_context == NULL) {
|
||||
uwsgi_error("zmq_init()");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return uwsgi.zmq_context;
|
||||
}
|
||||
|
||||
void uwsgi_zeromq_init_sockets() {
|
||||
|
||||
uwsgi_zeromq_init();
|
||||
uwsgi_zeromq_init();
|
||||
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while(uwsgi_sock) {
|
||||
if (!uwsgi_sock->proto_name || strcmp(uwsgi_sock->proto_name, "zmq")) {
|
||||
goto zmq_next;
|
||||
}
|
||||
uwsgi_proto_zeromq_setup(uwsgi_sock);
|
||||
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
|
||||
while (uwsgi_sock) {
|
||||
if (!uwsgi_sock->proto_name || strcmp(uwsgi_sock->proto_name, "zmq")) {
|
||||
goto zmq_next;
|
||||
}
|
||||
uwsgi_proto_zeromq_setup(uwsgi_sock);
|
||||
zmq_next:
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
uwsgi_sock = uwsgi_sock->next;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -80,6 +85,7 @@ static int uwsgi_mongrel2_json_parse(json_t * root, struct wsgi_request *wsgi_re
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REQUEST_METHOD", 14, json_val, strlen(json_val));
|
||||
}
|
||||
|
||||
// pretty easy, we get the file and we map it to wsgi_req->post_file, uWSGI read api will automatically use this
|
||||
if ((json_val = uwsgi_mongrel2_json_get_string(root, "x-mongrel2-upload-done"))) {
|
||||
wsgi_req->post_file = fopen(json_val, "r");
|
||||
if (!wsgi_req->post_file) {
|
||||
@@ -126,12 +132,12 @@ static int uwsgi_mongrel2_json_parse(json_t * root, struct wsgi_request *wsgi_re
|
||||
|
||||
if ((json_val = uwsgi_mongrel2_json_get_string(root, "x-forwarded-for"))) {
|
||||
char *colon = strchr(json_val, ',');
|
||||
if (colon) {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, colon + 1, (colon + 1) - json_val);
|
||||
}
|
||||
else {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, json_val, strlen(json_val));
|
||||
}
|
||||
if (colon) {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, colon + 1, (colon + 1) - json_val);
|
||||
}
|
||||
else {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, json_val, strlen(json_val));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +234,7 @@ static int uwsgi_mongrel2_tnetstring_parse(struct wsgi_request *wsgi_req, char *
|
||||
if (!uwsgi_strncmp("host", 4, key, keylen)) {
|
||||
char *colon = memchr(val, ':', vallen);
|
||||
if (colon) {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, colon + 1, vallen - ((colon + 1)-val));
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, colon + 1, vallen - ((colon + 1) - val));
|
||||
}
|
||||
else {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_PORT", 11, "80", 2);
|
||||
@@ -250,11 +256,11 @@ static int uwsgi_mongrel2_tnetstring_parse(struct wsgi_request *wsgi_req, char *
|
||||
else if (!uwsgi_strncmp("x-forwarded-for", 15, key, keylen)) {
|
||||
char *colon = memchr(val, ',', vallen);
|
||||
if (colon) {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, colon + 1, (colon + 1) - val);
|
||||
}
|
||||
else {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, val, vallen);
|
||||
}
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, colon + 1, (colon + 1) - val);
|
||||
}
|
||||
else {
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "REMOTE_ADDR", 11, val, vallen);
|
||||
}
|
||||
}
|
||||
else if (!uwsgi_strncmp("x-mongrel2-upload-start", 23, key, keylen)) {
|
||||
async_upload += 1;
|
||||
@@ -266,9 +272,9 @@ static int uwsgi_mongrel2_tnetstring_parse(struct wsgi_request *wsgi_req, char *
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "SERVER_NAME", 11, uwsgi.hostname, uwsgi.hostname_len);
|
||||
|
||||
if (query_string == NULL) {
|
||||
// always set QUERY_STRING
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, "", 0);
|
||||
}
|
||||
// always set QUERY_STRING
|
||||
wsgi_req->uh->pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, "", 0);
|
||||
}
|
||||
|
||||
// reject uncomplete upload
|
||||
if (async_upload == 1) {
|
||||
@@ -277,6 +283,7 @@ static int uwsgi_mongrel2_tnetstring_parse(struct wsgi_request *wsgi_req, char *
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fake function, we parse requests in the accept phase
|
||||
int uwsgi_proto_zeromq_parser(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_OK;
|
||||
}
|
||||
@@ -284,130 +291,35 @@ int uwsgi_proto_zeromq_parser(struct wsgi_request *wsgi_req) {
|
||||
void uwsgi_proto_zeromq_thread_fixup(struct uwsgi_socket *uwsgi_sock, int async_id) {
|
||||
|
||||
void *tmp_zmq_pull = zmq_socket(uwsgi.zmq_context, ZMQ_PULL);
|
||||
if (tmp_zmq_pull == NULL) {
|
||||
uwsgi_error("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
if (tmp_zmq_pull == NULL) {
|
||||
uwsgi_error("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (zmq_connect(tmp_zmq_pull, uwsgi_sock->receiver) < 0) {
|
||||
uwsgi_error("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
if (zmq_connect(tmp_zmq_pull, uwsgi_sock->receiver) < 0) {
|
||||
uwsgi_error("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_setspecific(uwsgi_sock->key, tmp_zmq_pull);
|
||||
|
||||
#ifdef ZMQ_FD
|
||||
if (uwsgi.threads > 1) {
|
||||
size_t zmq_socket_len = sizeof(int);
|
||||
if (zmq_getsockopt(pthread_getspecific(uwsgi_sock->key), ZMQ_FD, &uwsgi_sock->fd_threads[async_id], &zmq_socket_len) < 0) {
|
||||
uwsgi_error("zmq_getsockopt()");
|
||||
exit(1);
|
||||
size_t zmq_socket_len = sizeof(int);
|
||||
if (zmq_getsockopt(pthread_getspecific(uwsgi_sock->key), ZMQ_FD, &uwsgi_sock->fd_threads[async_id], &zmq_socket_len) < 0) {
|
||||
uwsgi_error("zmq_getsockopt()");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->retry[async_id] = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void uwsgi_proto_zeromq_setup(struct uwsgi_socket *uwsgi_sock) {
|
||||
|
||||
char *responder = strchr(uwsgi_sock->name, ',');
|
||||
if (!responder) {
|
||||
uwsgi_log("invalid zeromq address\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->receiver = uwsgi_concat2n(uwsgi_sock->name, responder - uwsgi_sock->name, "", 0);
|
||||
responder++;
|
||||
|
||||
uwsgi_sock->pub = zmq_socket(uwsgi.zmq_context, ZMQ_PUB);
|
||||
if (uwsgi_sock->pub == NULL) {
|
||||
uwsgi_error("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
// generate uuid
|
||||
uuid_t uuid_zmq;
|
||||
uuid_generate(uuid_zmq);
|
||||
uuid_unparse(uuid_zmq, uwsgi_sock->uuid);
|
||||
|
||||
if (zmq_setsockopt(uwsgi_sock->pub, ZMQ_IDENTITY, uwsgi_sock->uuid, 36) < 0) {
|
||||
uwsgi_error("zmq_setsockopt()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (zmq_connect(uwsgi_sock->pub, responder) < 0) {
|
||||
uwsgi_error("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("zeromq UUID for responder %s on worker %d: %.*s\n", responder, uwsgi.mywid, 36, uwsgi_sock->uuid);
|
||||
|
||||
uwsgi_sock->proto = uwsgi_proto_zeromq_parser;
|
||||
uwsgi_sock->proto_accept = uwsgi_proto_zeromq_accept;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_zeromq_close;
|
||||
/*
|
||||
uwsgi_sock->proto_write = uwsgi_proto_zeromq_write;
|
||||
uwsgi_sock->proto_write_header = uwsgi_proto_zeromq_write_header;
|
||||
uwsgi_sock->proto_sendfile = uwsgi_proto_zeromq_sendfile;
|
||||
*/
|
||||
|
||||
uwsgi_sock->proto_thread_fixup = uwsgi_proto_zeromq_thread_fixup;
|
||||
|
||||
uwsgi_sock->edge_trigger = 1;
|
||||
uwsgi_sock->retry = uwsgi_malloc(sizeof(int) * uwsgi.threads);
|
||||
uwsgi_sock->retry[0] = 1;
|
||||
|
||||
// inform loop engine about edge trigger status
|
||||
uwsgi.is_et = 1;
|
||||
|
||||
|
||||
// initialize a lock for multithread usage
|
||||
if (uwsgi.threads > 1) {
|
||||
pthread_mutex_init(&uwsgi_sock->lock, NULL);
|
||||
}
|
||||
|
||||
// one pull per-thread
|
||||
if (pthread_key_create(&uwsgi_sock->key, NULL)) {
|
||||
uwsgi_error("pthread_key_create()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void *tmp_zmq_pull = zmq_socket(uwsgi.zmq_context, ZMQ_PULL);
|
||||
if (tmp_zmq_pull == NULL) {
|
||||
uwsgi_error("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
if (zmq_connect(tmp_zmq_pull, uwsgi_sock->receiver) < 0) {
|
||||
uwsgi_error("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_setspecific(uwsgi_sock->key, tmp_zmq_pull);
|
||||
|
||||
#ifdef ZMQ_FD
|
||||
size_t zmq_socket_len = sizeof(int);
|
||||
if (zmq_getsockopt(pthread_getspecific(uwsgi_sock->key), ZMQ_FD, &uwsgi_sock->fd, &zmq_socket_len) < 0) {
|
||||
uwsgi_error("zmq_getsockopt()");
|
||||
exit(1);
|
||||
}
|
||||
if (uwsgi.threads > 1) {
|
||||
uwsgi_sock->fd_threads = uwsgi_malloc(sizeof(int) * uwsgi.threads);
|
||||
uwsgi_sock->fd_threads[0] = uwsgi_sock->fd;
|
||||
}
|
||||
#else
|
||||
uwsgi_sock->fd = -1;
|
||||
#endif
|
||||
|
||||
uwsgi_sock->bound = 1;
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
|
||||
uwsgi_sock->recv_flag = ZMQ_DONTWAIT;
|
||||
#else
|
||||
uwsgi_sock->recv_flag = ZMQ_NOBLOCK;
|
||||
#endif
|
||||
// fake function, the bosy is i na file or completely in memory
|
||||
ssize_t uwsgi_proto_zeromq_read_body(struct wsgi_request *wsgi_req, char *buf, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int uwsgi_proto_zeromq_accept(struct wsgi_request *wsgi_req, int fd) {
|
||||
|
||||
zmq_msg_t message;
|
||||
@@ -527,19 +439,14 @@ int uwsgi_proto_zeromq_accept(struct wsgi_request *wsgi_req, int fd) {
|
||||
memcpy((char *) wsgi_req->proto_parser_buf + req_uuid_len + 1 + resp_id_len + 1 + req_id_len, ", ", 2);
|
||||
wsgi_req->proto_parser_pos = (uint64_t) req_uuid_len + 1 + resp_id_len + 1 + req_id_len + 1 + 1;
|
||||
|
||||
// handle post data
|
||||
// handle post data (in memory)
|
||||
if (wsgi_req->post_cl > 0 && !wsgi_req->post_file) {
|
||||
if (uwsgi_netstring(post_data, message_size - (post_data - message_ptr), &message_ptr, &wsgi_req->post_cl)) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("post_size: %d\n", wsgi_req->post_cl);
|
||||
#endif
|
||||
wsgi_req->post_file = tmpfile();
|
||||
if (fwrite(message_ptr, wsgi_req->post_cl, 1, wsgi_req->post_file) != 1) {
|
||||
uwsgi_error("fwrite()");
|
||||
zmq_msg_close(&message);
|
||||
goto retry;
|
||||
}
|
||||
rewind(wsgi_req->post_file);
|
||||
wsgi_req->post_read_buf = uwsgi_malloc(wsgi_req->post_cl);
|
||||
memcpy(wsgi_req->post_read_buf, message_ptr, wsgi_req->post_cl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,10 +470,6 @@ retry:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void uwsgi_proto_zeromq_free(void *data, void *hint) {
|
||||
free(data);
|
||||
}
|
||||
|
||||
void uwsgi_proto_zeromq_close(struct wsgi_request *wsgi_req) {
|
||||
zmq_msg_t reply;
|
||||
|
||||
@@ -574,82 +477,188 @@ void uwsgi_proto_zeromq_close(struct wsgi_request *wsgi_req) {
|
||||
if (!wsgi_req->proto_parser_pos)
|
||||
return;
|
||||
|
||||
zmq_msg_init_data(&reply, wsgi_req->proto_parser_buf, wsgi_req->proto_parser_pos, uwsgi_proto_zeromq_free, NULL);
|
||||
if (uwsgi.threads > 1) pthread_mutex_lock(&wsgi_req->socket->lock);
|
||||
// no need to pass a free function (the buffer will be freed during cloe_request)
|
||||
zmq_msg_init_data(&reply, wsgi_req->proto_parser_buf, wsgi_req->proto_parser_pos, NULL, NULL);
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_lock(&wsgi_req->socket->lock);
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
|
||||
if (zmq_sendmsg(wsgi_req->socket->pub, &reply, 0)) {
|
||||
uwsgi_error("uwsgi_proto_zeromq_close()/zmq_sendmsg()");
|
||||
#else
|
||||
if (zmq_send(wsgi_req->socket->pub, &reply, 0)) {
|
||||
uwsgi_error("uwsgi_proto_zeromq_close()/zmq_send()");
|
||||
#endif
|
||||
uwsgi_error("zmq_send()");
|
||||
}
|
||||
if (uwsgi.threads > 1) pthread_mutex_unlock(&wsgi_req->socket->lock);
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_unlock(&wsgi_req->socket->lock);
|
||||
zmq_msg_close(&reply);
|
||||
|
||||
}
|
||||
|
||||
|
||||
ssize_t uwsgi_proto_zeromq_write(struct wsgi_request * wsgi_req, char *buf, size_t len) {
|
||||
int uwsgi_proto_zeromq_write(struct wsgi_request *wsgi_req, char *buf, size_t len) {
|
||||
zmq_msg_t reply;
|
||||
char *zmq_body;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if (zmq_msg_init_size(&reply, wsgi_req->proto_parser_pos + len)) {
|
||||
uwsgi_error("uwsgi_proto_zeromq_write()/zmq_msg_init_size()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
zmq_body = uwsgi_concat2n(wsgi_req->proto_parser_buf, (int) wsgi_req->proto_parser_pos, buf, (int) len);
|
||||
|
||||
//uwsgi_log("|%.*s|\n", (int)wsgi_req->proto_parser_pos+len, zmq_body);
|
||||
char *zmq_body = zmq_msg_data(&reply);
|
||||
memcpy(zmq_body, wsgi_req->proto_parser_buf, wsgi_req->proto_parser_pos);
|
||||
memcpy(zmq_body + wsgi_req->proto_parser_pos, buf, len);
|
||||
|
||||
zmq_msg_init_data(&reply, zmq_body, wsgi_req->proto_parser_pos + len, uwsgi_proto_zeromq_free, NULL);
|
||||
if (uwsgi.threads > 1) pthread_mutex_lock(&wsgi_req->socket->lock);
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_lock(&wsgi_req->socket->lock);
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
|
||||
if (zmq_sendmsg(wsgi_req->socket->pub, &reply, 0)) {
|
||||
#else
|
||||
if (zmq_send(wsgi_req->socket->pub, &reply, 0)) {
|
||||
#endif
|
||||
if (!uwsgi.ignore_write_errors) {
|
||||
uwsgi_error("zmq_send()");
|
||||
}
|
||||
wsgi_req->write_errors++;
|
||||
if (uwsgi.threads > 1) pthread_mutex_unlock(&wsgi_req->socket->lock);
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_unlock(&wsgi_req->socket->lock);
|
||||
zmq_msg_close(&reply);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (uwsgi.threads > 1) pthread_mutex_unlock(&wsgi_req->socket->lock);
|
||||
if (uwsgi.threads > 1)
|
||||
pthread_mutex_unlock(&wsgi_req->socket->lock);
|
||||
zmq_msg_close(&reply);
|
||||
|
||||
return len;
|
||||
return UWSGI_OK;
|
||||
}
|
||||
|
||||
ssize_t uwsgi_proto_zeromq_sendfile(struct wsgi_request * wsgi_req) {
|
||||
/*
|
||||
|
||||
ssize_t len;
|
||||
char buf[65536];
|
||||
size_t remains = wsgi_req->sendfile_fd_size - wsgi_req->sendfile_fd_pos;
|
||||
we have a problem... recent Mongrel2 releases introduced a ring buffer that limit the amount of messages we can send (or better, the amount of
|
||||
messages mongrel2 is able to manage). If we send a big static file we can fill that buffer immediately. How to deal with this ? We know that the
|
||||
message ring can contains a fixed amount of messages. We could try to split the file in chunks (upto the maximum number supported by a specific mongrel2 instance).
|
||||
This is suboptimal, but there are no better solutions for now. Before you ask: do you really think that sending a single message with a 2GB file is a good approach ?????
|
||||
By the way, for now, waiting for a better approach, we use a 2MB buffer. Should support flawlessly files up to 32MB without being rejected by mongrel2. For bigger files you
|
||||
can tune it to higher values (or increase the mongrel2 ring buffer)
|
||||
|
||||
wsgi_req->sendfile_fd_chunk = 65536;
|
||||
*/
|
||||
|
||||
if (uwsgi.async > 1) {
|
||||
len = read(wsgi_req->sendfile_fd, buf, UMIN(remains, wsgi_req->sendfile_fd_chunk));
|
||||
if (len != (int) UMIN(remains, wsgi_req->sendfile_fd_chunk)) {
|
||||
uwsgi_error("read()");
|
||||
return -1;
|
||||
}
|
||||
wsgi_req->sendfile_fd_pos += len;
|
||||
return uwsgi_proto_zeromq_write(wsgi_req, buf, len);
|
||||
#define UWSGI_MONGREL2_MAX_MSGSIZE 2*1024*1024
|
||||
int uwsgi_proto_zeromq_sendfile(struct wsgi_request *wsgi_req, int fd, size_t pos, size_t len) {
|
||||
|
||||
size_t chunk_size = UMIN( len - wsgi_req->write_pos, UWSGI_MONGREL2_MAX_MSGSIZE);
|
||||
char *tmp_buf = uwsgi_malloc(chunk_size);
|
||||
ssize_t rlen = read(fd, tmp_buf, chunk_size);
|
||||
if (rlen <= 0) {
|
||||
free(tmp_buf);
|
||||
return -1;
|
||||
}
|
||||
wsgi_req->write_pos += rlen;
|
||||
if (uwsgi_proto_zeromq_write(wsgi_req, tmp_buf, rlen) < 0) {
|
||||
free(tmp_buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (remains) {
|
||||
len = read(wsgi_req->sendfile_fd, buf, UMIN(remains, wsgi_req->sendfile_fd_chunk));
|
||||
if (len != (int) UMIN(remains, wsgi_req->sendfile_fd_chunk)) {
|
||||
uwsgi_error("read()");
|
||||
return -1;
|
||||
}
|
||||
wsgi_req->sendfile_fd_pos += len;
|
||||
len = uwsgi_proto_zeromq_write(wsgi_req, buf, len);
|
||||
remains = wsgi_req->sendfile_fd_size - wsgi_req->sendfile_fd_pos;
|
||||
free(tmp_buf);
|
||||
|
||||
if (wsgi_req->write_pos == len) {
|
||||
return UWSGI_OK;
|
||||
}
|
||||
return UWSGI_AGAIN;
|
||||
}
|
||||
|
||||
return wsgi_req->sendfile_fd_pos;
|
||||
void uwsgi_proto_zeromq_setup(struct uwsgi_socket *uwsgi_sock) {
|
||||
|
||||
char *responder = strchr(uwsgi_sock->name, ',');
|
||||
if (!responder) {
|
||||
uwsgi_log("invalid zeromq address\n");
|
||||
exit(1);
|
||||
}
|
||||
uwsgi_sock->receiver = uwsgi_concat2n(uwsgi_sock->name, responder - uwsgi_sock->name, "", 0);
|
||||
responder++;
|
||||
|
||||
uwsgi_sock->pub = zmq_socket(uwsgi.zmq_context, ZMQ_PUB);
|
||||
if (uwsgi_sock->pub == NULL) {
|
||||
uwsgi_error("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
// generate uuid
|
||||
uuid_t uuid_zmq;
|
||||
uuid_generate(uuid_zmq);
|
||||
uuid_unparse(uuid_zmq, uwsgi_sock->uuid);
|
||||
|
||||
if (zmq_setsockopt(uwsgi_sock->pub, ZMQ_IDENTITY, uwsgi_sock->uuid, 36) < 0) {
|
||||
uwsgi_error("zmq_setsockopt()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (zmq_connect(uwsgi_sock->pub, responder) < 0) {
|
||||
uwsgi_error("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uwsgi_log("zeromq UUID for responder %s on worker %d: %.*s\n", responder, uwsgi.mywid, 36, uwsgi_sock->uuid);
|
||||
|
||||
uwsgi_sock->proto = uwsgi_proto_zeromq_parser;
|
||||
uwsgi_sock->proto_accept = uwsgi_proto_zeromq_accept;
|
||||
uwsgi_sock->proto_prepare_headers = uwsgi_proto_base_prepare_headers;
|
||||
uwsgi_sock->proto_add_header = uwsgi_proto_base_add_header;
|
||||
uwsgi_sock->proto_fix_headers = uwsgi_proto_base_fix_headers;
|
||||
uwsgi_sock->proto_read_body = uwsgi_proto_zeromq_read_body;
|
||||
uwsgi_sock->proto_write = uwsgi_proto_zeromq_write;
|
||||
uwsgi_sock->proto_write_headers = uwsgi_proto_zeromq_write;
|
||||
uwsgi_sock->proto_sendfile = uwsgi_proto_zeromq_sendfile;
|
||||
uwsgi_sock->proto_close = uwsgi_proto_zeromq_close;
|
||||
|
||||
uwsgi_sock->proto_thread_fixup = uwsgi_proto_zeromq_thread_fixup;
|
||||
|
||||
uwsgi_sock->edge_trigger = 1;
|
||||
uwsgi_sock->retry = uwsgi_malloc(sizeof(int) * uwsgi.threads);
|
||||
uwsgi_sock->retry[0] = 1;
|
||||
|
||||
// inform loop engine about edge trigger status
|
||||
uwsgi.is_et = 1;
|
||||
|
||||
|
||||
// initialize a lock for multithread usage
|
||||
if (uwsgi.threads > 1) {
|
||||
pthread_mutex_init(&uwsgi_sock->lock, NULL);
|
||||
}
|
||||
|
||||
// one pull per-thread
|
||||
if (pthread_key_create(&uwsgi_sock->key, NULL)) {
|
||||
uwsgi_error("pthread_key_create()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void *tmp_zmq_pull = zmq_socket(uwsgi.zmq_context, ZMQ_PULL);
|
||||
if (tmp_zmq_pull == NULL) {
|
||||
uwsgi_error("zmq_socket()");
|
||||
exit(1);
|
||||
}
|
||||
if (zmq_connect(tmp_zmq_pull, uwsgi_sock->receiver) < 0) {
|
||||
uwsgi_error("zmq_connect()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_setspecific(uwsgi_sock->key, tmp_zmq_pull);
|
||||
|
||||
#ifdef ZMQ_FD
|
||||
size_t zmq_socket_len = sizeof(int);
|
||||
if (zmq_getsockopt(pthread_getspecific(uwsgi_sock->key), ZMQ_FD, &uwsgi_sock->fd, &zmq_socket_len) < 0) {
|
||||
uwsgi_error("zmq_getsockopt()");
|
||||
exit(1);
|
||||
}
|
||||
if (uwsgi.threads > 1) {
|
||||
uwsgi_sock->fd_threads = uwsgi_malloc(sizeof(int) * uwsgi.threads);
|
||||
uwsgi_sock->fd_threads[0] = uwsgi_sock->fd;
|
||||
}
|
||||
#else
|
||||
uwsgi_sock->fd = -1;
|
||||
#endif
|
||||
|
||||
uwsgi_sock->bound = 1;
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
|
||||
uwsgi_sock->recv_flag = ZMQ_DONTWAIT;
|
||||
#else
|
||||
uwsgi_sock->recv_flag = ZMQ_NOBLOCK;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -91,8 +91,6 @@ setup(name='uWSGI',
|
||||
description='The uWSGI server',
|
||||
author='Unbit',
|
||||
author_email='info@unbit.it',
|
||||
download_url='http://projects.unbit.it/downloads/uwsgi-%s.tar.gz'
|
||||
% (uc.uwsgi_version),
|
||||
license='GPL2',
|
||||
py_modules=['uwsgidecorators'],
|
||||
distclass=uWSGIDistribution,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
Ring Test Suite
|
||||
================
|
||||
|
||||
how to build and run
|
||||
---------------------
|
||||
|
||||
* cd UWSGIROOT
|
||||
* cd t/ring
|
||||
* lein uberjar
|
||||
* cd ../..
|
||||
* uwsgi t/ring/config.ini
|
||||
* open http://localhost:9090 in your browser
|
||||
|
||||
run cases in jetty
|
||||
-------------------
|
||||
|
||||
* lein ring server
|
||||
* open http://localhost:3000 in your browser
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[uwsgi]
|
||||
http-socket = :9090
|
||||
http-socket-modifier1 = 8
|
||||
http-socket-modifier2 = 1
|
||||
|
||||
jvm-classpath = plugins/jvm/uwsgi.jar
|
||||
jvm-classpath = t/ring/target/uwsgi-ring-tests-0.0.1-standalone.jar
|
||||
|
||||
jvm-class = uwsgi/ring/tests/app
|
||||
|
||||
ring-app = uwsgi.ring.tests.app/app
|
||||
@@ -0,0 +1,10 @@
|
||||
(defproject unbit/uwsgi-ring-tests "0.0.1"
|
||||
:description "uwsgi-ring-tests: test cases for uwsgi ring server"
|
||||
:dependencies [[org.clojure/clojure "1.4.0"]
|
||||
[compojure "1.1.5"]
|
||||
[ring/ring "1.1.0"]]
|
||||
|
||||
:source-paths ["src"]
|
||||
|
||||
:aot [uwsgi.ring.tests.app]
|
||||
)
|
||||
@@ -0,0 +1,29 @@
|
||||
(ns uwsgi.ring.tests.app
|
||||
(:use compojure.core)
|
||||
(:use [ring.middleware params
|
||||
keyword-params
|
||||
nested-params
|
||||
multipart-params])
|
||||
(:require [compojure.route :as route]
|
||||
[uwsgi.ring.tests.basic :as basic]
|
||||
[uwsgi.ring.tests.body :as body]
|
||||
[uwsgi.ring.tests.simple :as simple]
|
||||
[uwsgi.ring.tests.upload :as upload])
|
||||
(:gen-class
|
||||
:main true))
|
||||
|
||||
(defn app-routes [req]
|
||||
(if (= (get req :uri) "/")
|
||||
(basic/index-page req)
|
||||
((routes simple/app-routes body/app-routes upload/app-routes (route/not-found "<h1>Page not found</h1>")) req)))
|
||||
|
||||
(def app
|
||||
(-> app-routes
|
||||
wrap-keyword-params
|
||||
wrap-nested-params
|
||||
wrap-params
|
||||
wrap-multipart-params))
|
||||
|
||||
(defn -main [& args]
|
||||
(println "uwsgi ring tests app loaded"))
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
(ns uwsgi.ring.tests.basic)
|
||||
|
||||
(defn index-page [req] {:status 200
|
||||
:headers { "Content-Type" "text/html" , "Server" "uWSGI" }
|
||||
:body (str "<h1>Ring test suites</h1>"
|
||||
"<h2>Simple tests</h2>"
|
||||
"<ul>"
|
||||
"<li><a href='/hello'>hello</a></li>"
|
||||
"<li><a href='/echo?msg=abc'>echo</a></li>"
|
||||
"<li><a href='/palindrome?msg=abc'>palindrome</a></li>"
|
||||
"</ul>"
|
||||
"<h2>Body type tests</h2>"
|
||||
"<ul>"
|
||||
"<li><a href='/sequence'>sequence</a></li>"
|
||||
"<li><a href='/file'>file</a></li>"
|
||||
"<li><a href='/stream'>stream</a></li>"
|
||||
"</ul>"
|
||||
"<h2>Upload tests</h2>"
|
||||
"<form action='/upload' enctype='multipart/form-data' method='post'>"
|
||||
"<p>"
|
||||
"Please select a file<br>"
|
||||
"<input type='file' name='file' size='40'>"
|
||||
"</p>"
|
||||
"<input type='submit' value='Upload'>"
|
||||
"</form>"
|
||||
"<h2>Other tests</h2>"
|
||||
"<ul>"
|
||||
"<li>...</li>"
|
||||
"</ul>")})
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
(ns uwsgi.ring.tests.body
|
||||
(:use [compojure.core]))
|
||||
|
||||
; generating primary numbers
|
||||
; http://clojuredocs.org/clojure_core/clojure.core/lazy-seq#example_1000
|
||||
(defn sieve [s]
|
||||
(cons (first s)
|
||||
(lazy-seq (sieve (filter #(not= 0 (mod % (first s)))
|
||||
(rest s))))))
|
||||
|
||||
(defn numsequence [] (take 20 (sieve (iterate inc 2))))
|
||||
|
||||
(defn file [] (java.io.File. "CONTRIBUTORS"))
|
||||
|
||||
(defn stream [] (java.io.FileInputStream. (java.io.File. "CONTRIBUTORS")))
|
||||
|
||||
(defroutes app-routes
|
||||
(GET "/sequence" [] (numsequence))
|
||||
(GET "/file" [] (file))
|
||||
(GET "/stream" [] (stream)))
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns uwsgi.ring.tests.simple
|
||||
(:use [compojure.core]) )
|
||||
|
||||
(defn hello [] "Hello, World!")
|
||||
|
||||
(defn echo [msg] msg)
|
||||
|
||||
(defn palindrome [msg] (clojure.string/reverse msg) )
|
||||
|
||||
(defroutes app-routes
|
||||
(GET "/hello" [] (hello) )
|
||||
(GET "/echo" [msg] (echo msg) )
|
||||
(GET "/palindrome" [msg] (palindrome msg) )
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
(ns uwsgi.ring.tests.upload
|
||||
(:use [compojure.core]))
|
||||
|
||||
(defn upload-file [fname fsize fbody] {
|
||||
:status 200
|
||||
:headers { "Content-Type" "text/html" , "Server" "uWSGI" }
|
||||
:body (str "<h1>Uploaded file</h1>"
|
||||
"<ul>"
|
||||
"<li>" fname "</li>"
|
||||
"<li>" fsize "</li>"
|
||||
"</ul>")})
|
||||
|
||||
(defroutes app-routes
|
||||
(POST "/upload" {params :params}
|
||||
(let [file (params :file)
|
||||
file-name (file :filename)
|
||||
file-size (file :size)
|
||||
file-body (file :tempfile)]
|
||||
(upload-file file-name file-size file-body))))
|
||||
|
||||
@@ -274,14 +274,15 @@ extern "C" {
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
#ifdef __sun__
|
||||
#if defined(__sun__)
|
||||
#define WAIT_ANY (-1)
|
||||
#include <sys/filio.h>
|
||||
#define PRIO_MAX 20
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#if defined(__HAIKU__) || defined(__CYGWIN__)
|
||||
#define WAIT_ANY (-1)
|
||||
#define PRIO_MAX 20
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
@@ -293,6 +294,7 @@ extern "C" {
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/devpoll.h>
|
||||
#elif defined(__HAIKU__)
|
||||
#elif defined(__CYGWIN__)
|
||||
#else
|
||||
#include <sys/event.h>
|
||||
#endif
|
||||
@@ -327,6 +329,18 @@ extern "C" {
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#define __WINCRYPT_H__
|
||||
#include <windows.h>
|
||||
#ifdef UWSGI_UUID
|
||||
#undef uuid_t
|
||||
#endif
|
||||
#undef CMSG_DATA
|
||||
#define CMSG_DATA(cmsg) \
|
||||
((unsigned char *) ((struct cmsghdr *)(cmsg) + 1))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
struct uwsgi_buffer {
|
||||
@@ -1455,9 +1469,9 @@ struct uwsgi_router {
|
||||
struct uwsgi_clock *next;
|
||||
};
|
||||
|
||||
struct uwsgi_subscribe_slot;
|
||||
struct uwsgi_stats_pusher;
|
||||
struct uwsgi_stats_pusher_instance;
|
||||
struct uwsgi_subscribe_slot;
|
||||
struct uwsgi_stats_pusher;
|
||||
struct uwsgi_stats_pusher_instance;
|
||||
|
||||
#define UWSGI_PROTO_MIN_CHECK 4
|
||||
#define UWSGI_PROTO_MAX_CHECK 23
|
||||
@@ -2929,18 +2943,10 @@ int uwsgi_proto_scgi_parser(struct wsgi_request *);
|
||||
uint16_t proto_base_add_uwsgi_var(struct wsgi_request *, char *, uint16_t, char *, uint16_t);
|
||||
|
||||
#ifdef UWSGI_ZEROMQ
|
||||
void uwsgi_proto_zeromq_setup(struct uwsgi_socket *);
|
||||
ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *, char *, size_t len);
|
||||
int uwsgi_proto_zeromq_accept(struct wsgi_request *, int);
|
||||
void uwsgi_proto_zeromq_close(struct wsgi_request *);
|
||||
ssize_t uwsgi_proto_zeromq_writev_header(struct wsgi_request *, struct iovec *, size_t);
|
||||
ssize_t uwsgi_proto_zeromq_writev(struct wsgi_request *, struct iovec *, size_t);
|
||||
ssize_t uwsgi_proto_zeromq_write(struct wsgi_request *, char *, size_t);
|
||||
ssize_t uwsgi_proto_zeromq_write_header(struct wsgi_request *, char *, size_t);
|
||||
ssize_t uwsgi_proto_zeromq_sendfile(struct wsgi_request *);
|
||||
int uwsgi_proto_zeromq_parser(struct wsgi_request *);
|
||||
void *uwsgi_zeromq_init(void);
|
||||
void uwsgi_zeromq_init_sockets(void);
|
||||
void uwsgi_proto_zeromq_setup(struct uwsgi_socket *);
|
||||
ssize_t uwsgi_zeromq_logger(struct uwsgi_logger *, char *, size_t len);
|
||||
void *uwsgi_zeromq_init(void);
|
||||
void uwsgi_zeromq_init_sockets(void);
|
||||
#endif
|
||||
|
||||
int uwsgi_num2str2(int, char *);
|
||||
@@ -3387,6 +3393,7 @@ struct uwsgi_stats_pusher_instance;
|
||||
struct uwsgi_stats_pusher {
|
||||
char *name;
|
||||
void (*func) (struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
|
||||
int raw;
|
||||
struct uwsgi_stats_pusher *next;
|
||||
};
|
||||
|
||||
|
||||
+36
-8
@@ -1,6 +1,6 @@
|
||||
# uWSGI build system
|
||||
|
||||
uwsgi_version = '1.9-dev'
|
||||
uwsgi_version = '1.9'
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -228,7 +228,7 @@ def build_uwsgi(uc, print_only=False):
|
||||
continue
|
||||
p = p.strip()
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku' or uwsgi_os.startswith('CYGWIN'):
|
||||
continue
|
||||
epc += "UDEP(%s);" % p
|
||||
eplc += "ULEP(%s);" % p
|
||||
@@ -291,7 +291,7 @@ def build_uwsgi(uc, print_only=False):
|
||||
p = p.strip()
|
||||
|
||||
if p == 'ugreen':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku':
|
||||
if uwsgi_os == 'OpenBSD' or uwsgi_cpu[0:3] == 'arm' or uwsgi_os == 'Haiku' or uwsgi_os.startswith('CYGWIN'):
|
||||
continue
|
||||
path = 'plugins/%s' % p
|
||||
path = path.rstrip('/')
|
||||
@@ -311,6 +311,12 @@ def build_uwsgi(uc, print_only=False):
|
||||
p_cflags = cflags[:]
|
||||
p_cflags += up['CFLAGS']
|
||||
|
||||
if uwsgi_os.startswith('CYGWIN'):
|
||||
try:
|
||||
p_cflags.remove('-fstack-protector')
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
p_cflags.remove('-Wdeclaration-after-statement')
|
||||
except:
|
||||
@@ -640,6 +646,8 @@ class uConf(object):
|
||||
pass
|
||||
elif uwsgi_os == 'Darwin':
|
||||
locking_mode = 'osx_spinlock'
|
||||
elif uwsgi_os.startswith('CYGWIN'):
|
||||
locking_mode = 'windows_mutex'
|
||||
|
||||
if locking_mode == 'pthread_mutex':
|
||||
self.cflags.append('-DUWSGI_LOCK_USE_MUTEX')
|
||||
@@ -648,6 +656,8 @@ class uConf(object):
|
||||
self.cflags.append('-DUWSGI_LOCK_USE_POSIX_SEM')
|
||||
elif locking_mode == 'osx_spinlock':
|
||||
self.cflags.append('-DUWSGI_LOCK_USE_OSX_SPINLOCK')
|
||||
elif locking_mode == 'windows_mutex':
|
||||
self.cflags.append('-DUWSGI_LOCK_USE_WINDOWS_MUTEX')
|
||||
|
||||
if locking_mode == 'auto':
|
||||
report['locking'] = 'sysv semaphores'
|
||||
@@ -666,8 +676,10 @@ class uConf(object):
|
||||
if int(sun_major) >= 5:
|
||||
if int(sun_minor) >= 10:
|
||||
event_mode = 'port'
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD', 'OpenBSD', 'NetBSD'):
|
||||
elif uwsgi_os in ('Darwin', 'FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFly'):
|
||||
event_mode = 'kqueue'
|
||||
elif uwsgi_os.startswith('CYGWIN'):
|
||||
event_mode = 'poll'
|
||||
|
||||
if event_mode == 'epoll':
|
||||
self.cflags.append('-DUWSGI_EVENT_USE_EPOLL')
|
||||
@@ -677,6 +689,8 @@ class uConf(object):
|
||||
self.cflags.append('-DUWSGI_EVENT_USE_DEVPOLL')
|
||||
elif event_mode == 'port':
|
||||
self.cflags.append('-DUWSGI_EVENT_USE_PORT')
|
||||
elif event_mode == 'poll':
|
||||
self.cflags.append('-DUWSGI_EVENT_USE_POLL')
|
||||
|
||||
report['event'] = event_mode
|
||||
|
||||
@@ -758,8 +772,10 @@ class uConf(object):
|
||||
|
||||
if self.get('as_shared_library'):
|
||||
self.ldflags.append('-shared')
|
||||
self.ldflags.append('-fPIC')
|
||||
self.cflags.append('-fPIC')
|
||||
# on cygwin we do not need PIC (it is implicit)
|
||||
if not uwsgi_os.startswith('CYGWIN'):
|
||||
self.ldflags.append('-fPIC')
|
||||
self.cflags.append('-fPIC')
|
||||
self.cflags.append('-DUWSGI_AS_SHARED_LIBRARY')
|
||||
if uwsgi_os == 'Darwin':
|
||||
self.ldflags.append('-dynamiclib')
|
||||
@@ -829,7 +845,7 @@ class uConf(object):
|
||||
if self.has_include('uuid/uuid.h'):
|
||||
has_uuid = True
|
||||
self.cflags.append("-DUWSGI_UUID")
|
||||
if uwsgi_os == 'Linux' or os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so') or os.path.exists('/usr/lib64/libuuid.so') or os.path.exists('/usr/local/lib64/libuuid.so'):
|
||||
if uwsgi_os == 'Linux' or uwsgi_os.startswith('CYGWIN') or os.path.exists('/usr/lib/libuuid.so') or os.path.exists('/usr/local/lib/libuuid.so') or os.path.exists('/usr/lib64/libuuid.so') or os.path.exists('/usr/local/lib64/libuuid.so'):
|
||||
self.libs.append('-luuid')
|
||||
|
||||
if self.get('append_version'):
|
||||
@@ -1159,10 +1175,22 @@ def build_plugin(path, uc, cflags, ldflags, libs, name = None):
|
||||
except:
|
||||
pass
|
||||
|
||||
if uwsgi_os.startswith('CYGWIN'):
|
||||
try:
|
||||
p_cflags.remove('-fstack-protector')
|
||||
p_ldflags.remove('-fstack-protector')
|
||||
except:
|
||||
pass
|
||||
|
||||
#for ofile in up.OBJ_LIST:
|
||||
# gcc_list.insert(0,ofile)
|
||||
|
||||
gccline = "%s -fPIC %s -o %s.so %s %s %s %s" % (GCC, shared_flag, plugin_dest, ' '.join(uniq_warnings(p_cflags)), ' '.join(gcc_list), ' '.join(uniq_warnings(p_ldflags)), ' '.join(uniq_warnings(p_libs)) )
|
||||
need_pic = ' -fPIC'
|
||||
# on cygwin we do not need PIC
|
||||
if uwsgi_os.startswith('CYGWIN'):
|
||||
need_pic = ' -L. -luwsgi'
|
||||
|
||||
gccline = "%s%s %s -o %s.so %s %s %s %s" % (GCC, need_pic, shared_flag, plugin_dest, ' '.join(uniq_warnings(p_cflags)), ' '.join(gcc_list), ' '.join(uniq_warnings(p_ldflags)), ' '.join(uniq_warnings(p_libs)) )
|
||||
print("[%s] %s.so" % (GCC, plugin_dest))
|
||||
|
||||
ret = os.system(gccline)
|
||||
|
||||
Reference in New Issue
Block a user