Compare commits

...
28 Commits
Author SHA1 Message Date
Unbit b93dcbf46f removed download_url from setup.py 2013-03-17 08:10:12 +01:00
Unbit 8051a2bc98 prepare for 1.9 release 2013-03-17 07:15:24 +01:00
Unbit 78d8b221fc added --gevent-monkey-patch 2013-03-17 07:14:54 +01:00
Unbit d51cada284 second (and last i hope) part of mongrel2 support refactoring 2013-03-16 18:24:25 +01:00
Unbit 389eef9e88 first part of mongrel2 support refactoring 2013-03-16 18:02:11 +01:00
Unbit 270fb0c50d avoid routing loop 2013-03-16 16:48:26 +01:00
Unbit e7e9dfee88 fixed DragonFlyBSD support 2013-03-16 15:45:49 +01:00
Unbit 3bafae276d improved binary detection path on cygwin 2013-03-16 12:33:00 +01:00
Unbit cfebe2927d fixed lazy mode 2013-03-15 13:47:29 +01:00
Unbit 1d4294a845 added some comment for the statsd plugin 2013-03-15 11:34:19 +01:00
Unbit 12cfdd9864 added stats_pusher_statsd plugin 2013-03-15 11:32:08 +01:00
Unbit add930c517 fixed uuid support in cygwin 2013-03-15 07:31:41 +01:00
Unbit 32972978be added java support for cygwin 2013-03-13 17:50:56 +01:00
Unbit c8bad3550e added proper locking to windows 2013-03-13 15:51:14 +01:00
Unbit ecc55d789d added proper-locking to poll event mode 2013-03-13 15:03:30 +01:00
Unbit 88555e2c20 improved poll() support 2013-03-13 14:33:38 +01:00
Unbit ec2bfcd302 allows building router basicauth on cygwin 2013-03-13 11:14:32 +01:00
Unbit f1f81ed4c4 fixed python3 build 2013-03-13 11:00:05 +01:00
Unbit 87933cca26 another series of cygwin fixes 2013-03-13 10:51:33 +01:00
Unbit 2dcd8624a2 psgi support for windows 2013-03-13 10:12:24 +01:00
Unbit 7fcef76bbe experimental windows/cygwin support 2013-03-13 09:44:32 +01:00
Unbit 2a5c4e938d fixed requets overwrite in PATH_INFO rewrite (fixed typo) 2013-03-12 15:57:44 +01:00
Unbit 274eae27ef fixed requets overwrite in PATH_INFO rewrite 2013-03-12 15:56:30 +01:00
Unbit 207220bc50 fixed #180 2013-03-12 11:45:03 +01:00
Unbit fb8c4439c7 the whole ring test suite passes 2013-03-12 11:15:45 +01:00
Roberto De Ioris 894be9c41e let the /sequence ring test pass 2013-03-12 09:42:13 +01:00
unbit 0a4bff8963 Merge pull request #182 from guokr/master
Ring plugin tests
2013-03-12 00:27:11 -07:00
Mingli d515f3e279 add tests for ring plugin 2013-03-12 14:47:51 +08:00
38 changed files with 1015 additions and 257 deletions
+4
View File
@@ -1,5 +1,9 @@
*.o
*.py[co]
*.class
*.jar
/uwsgi
/uwsgibuild.*
/t/ring/target
-1
View File
@@ -1 +0,0 @@
object file for embedded files will be put here
+227
View File
@@ -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>
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+24
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+1
View File
@@ -52,5 +52,6 @@ struct uwsgi_gevent {
PyObject *signal_watcher;
PyObject **watchers;
int destroy;
int monkey;
};
+2 -2
View File
@@ -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) {
+2
View File
@@ -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);
+31 -8
View File
@@ -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;
}
+5 -2
View File
@@ -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
+2
View File
@@ -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},
+7 -4
View File
@@ -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 -1
View File
@@ -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"
+137
View File
@@ -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
View File
@@ -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
}
-2
View File
@@ -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,
+21
View File
@@ -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
+11
View File
@@ -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
+10
View File
@@ -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]
)
+29
View File
@@ -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"))
+30
View File
@@ -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>")})
+20
View File
@@ -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)))
+14
View File
@@ -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) )
)
+20
View File
@@ -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))))
+24 -17
View File
@@ -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
View File
@@ -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)