caching infrastructure (need optimizations)

This commit is contained in:
roberto@sirius
2010-12-09 19:54:37 +01:00
parent 7d6f93d1cb
commit b75ba73264
13 changed files with 379 additions and 74 deletions
-19
View File
@@ -1,19 +0,0 @@
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
void gil_real_get() {
PyEval_AcquireLock();
PyThreadState_Swap((PyThreadState *) pthread_getspecific(uwsgi.ut_save_key));
}
void gil_real_release() {
pthread_setspecific(uwsgi.ut_save_key, (void *) PyThreadState_Swap(NULL));
PyEval_ReleaseLock();
}
struct wsgi_request* threaded_current_wsgi_req() { return pthread_getspecific(uwsgi.ut_key); }
struct wsgi_request* simple_current_wsgi_req() { return uwsgi.wsgi_req; }
void gil_fake_get() {}
void gil_fake_release() {}
+73
View File
@@ -0,0 +1,73 @@
#include "uwsgi.h"
#ifdef UWSGI_LOCK_USE_MUTEX
// REMEMBER lock must contains space for both pthread_mutex_t and pthread_mutexattr_t !!!
void uwsgi_lock_init(void *lock) {
if (pthread_mutexattr_init((pthread_mutexattr_t *) lock)) {
uwsgi_log("unable to allocate mutexattr structure\n");
exit(1);
}
if (pthread_mutexattr_setpshared((pthread_mutexattr_t *) lock, PTHREAD_PROCESS_SHARED)) {
uwsgi_log("unable to share mutex\n");
exit(1);
}
if (pthread_mutex_init((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t), (pthread_mutexattr_t *) lock)) {
uwsgi_log("unable to initialize mutex\n");
exit(1);
}
}
void uwsgi_lock(void *lock) {
pthread_mutex_lock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t));
}
void uwsgi_unlock(void *lock) {
pthread_mutex_unlock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t));
}
#endif
#ifdef UWSGI_LOCK_USE_OSX_SPINLOCK
void uwsgi_lock_init(void *lock) {
memset(lock, 0, sizeof(OSSpinLock));
}
void uwsgi_lock(void *lock) {
OSSpinLockLock((OSSpinLock *) lock);
}
void uwsgi_unlock(void *lock) {
OSSpinLockUnlock((OSSpinLock *) lock);
}
#endif
#ifdef UWSGI_LOCK_USE_FLOCK
void uwsgi_lock_init(void *lock) {}
void uwsgi_lock(void *lock) {
if (flock((int) *lock, LOCK_EX)) { uwsgi_error("flock()"); }
}
void uwsgi_unlock(void *lock) {
if (flock((int) *lock, LOCK_UN)) { uwsgi_error("flock()"); }
}
#endif
+2
View File
@@ -85,10 +85,12 @@ void *simple_loop(void *arg1) {
continue;
}
if (wsgi_req_recv(wsgi_req)) {
continue;
}
uwsgi_close_request(wsgi_req);
}
+73 -12
View File
@@ -44,6 +44,8 @@ void master_loop(char **argv, char **environ) {
uint64_t master_cycles = 0;
uint64_t tmp_counter;
uint64_t current_time = time(NULL);
struct timeval last_respawn;
pid_t pid;
@@ -59,6 +61,9 @@ void master_loop(char **argv, char **environ) {
int master_has_children = 0;
struct pollfd *uwsgi_signal_poll;
char uwsgi_signal;
#ifdef UWSGI_UDP
struct pollfd uwsgi_poll[2];
int uwsgi_poll_size = 0;
@@ -80,7 +85,7 @@ void master_loop(char **argv, char **environ) {
int i,j;
struct timeval check_interval = {.tv_sec = 1,.tv_usec = 0 };
int check_interval = 1;
// release the GIL
//UWSGI_RELEASE_GIL
@@ -94,6 +99,19 @@ void master_loop(char **argv, char **environ) {
signal(SIGUSR1, (void *) &stats);
uwsgi_signal_poll = malloc(sizeof(struct pollfd) * uwsgi.numproc);
if (!uwsgi_signal_poll) {
uwsgi_error("malloc()");
exit(1);
}
memset(uwsgi_signal_poll, 0, sizeof(struct pollfd) * uwsgi.numproc);
for(i=1;i<=uwsgi.numproc;i++) {
uwsgi_log("adding %d to signal poll\n", uwsgi.workers[i].pipe[0]);
uwsgi_signal_poll[i-1].fd = uwsgi.workers[i].pipe[0];
uwsgi_signal_poll[i-1].events = POLLIN;
}
uwsgi.wsgi_req->buffer = uwsgi.async_buf[0];
#ifdef UWSGI_UDP
if (uwsgi.udp_socket) {
@@ -287,9 +305,9 @@ void master_loop(char **argv, char **environ) {
if (diedpid == 0) {
/* all processes ok, doing status scan after N seconds */
check_interval.tv_sec = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval.tv_sec)
check_interval.tv_sec = 1;
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval)
check_interval = 1;
#ifdef UWSGI_UDP
#ifdef UWSGI_MULTICAST
@@ -297,7 +315,7 @@ void master_loop(char **argv, char **environ) {
#else
if ((uwsgi.udp_socket && udp_fd >= 0)) {
#endif
rlen = poll(uwsgi_poll, uwsgi_poll_size, check_interval.tv_sec * 1000);
rlen = poll(uwsgi_poll, uwsgi_poll_size, check_interval * 1000);
if (rlen < 0) {
uwsgi_error("poll()");
}
@@ -405,16 +423,38 @@ void master_loop(char **argv, char **environ) {
}
else {
#endif
select(0, NULL, NULL, NULL, &check_interval);
rlen = poll(uwsgi_signal_poll, uwsgi.numproc, check_interval);
if (rlen < 0) {
uwsgi_error("poll()");
continue;
}
else if (rlen > 0) {
for(i=0;i<uwsgi.numproc;i++) {
if (uwsgi_signal_poll[i].revents & POLLIN) {
rlen = read(uwsgi_signal_poll[i].fd, &uwsgi_signal, 1);
if (rlen < 0) {
uwsgi_error("read()");
}
else if (rlen > 0) {
uwsgi_log("received uwsgi signal %d from worker %d\n", uwsgi_signal, i+1);
}
else {
uwsgi_log_verbose("lost connection with worker %d\n", i+1);
}
}
}
}
#ifdef UWSGI_UDP
}
#endif
current_time = time(NULL);
// checking logsize
if (uwsgi.logfile) {
uwsgi.shared->logsize = lseek(2, 0, SEEK_CUR);
}
master_cycles++;
working_workers = 0;
blocking_workers = 0;
@@ -440,9 +480,20 @@ void master_loop(char **argv, char **environ) {
uwsgi.workers[0].requests = tmp_counter;
}
check_interval.tv_sec = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval.tv_sec)
check_interval.tv_sec = 1;
// remove expired cache items
if (uwsgi.cache_max_items > 0) {
for(i=0;i<uwsgi.cache_max_items;i++) {
if (uwsgi.cache_items[i].expires) {
if (uwsgi.cache_items[i].expires < current_time) {
uwsgi_cache_del(uwsgi.cache_items[i].key, uwsgi.cache_items[i].keysize);
}
}
}
}
check_interval = uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL];
if (!check_interval)
check_interval = 1;
#ifdef __linux__
@@ -455,7 +506,7 @@ void master_loop(char **argv, char **environ) {
for (i = 1; i <= uwsgi.numproc; i++) {
/* first check for harakiri */
if (uwsgi.workers[i].harakiri > 0) {
if (uwsgi.workers[i].harakiri < time(NULL)) {
if (uwsgi.workers[i].harakiri < (time_t) current_time) {
/* first try to invoke the harakiri() custom handler */
/* TODO */
/* then brutally kill the worker */
@@ -496,7 +547,7 @@ void master_loop(char **argv, char **environ) {
}
else if (ucn->name[0] != 0 && ucn->type == CLUSTER_NODE_DYNAMIC) {
// if the last_seen attr is higher than 30 secs ago, mark the node as dead
if ( (time(NULL) - ucn->last_seen) > 30) {
if ( (current_time - ucn->last_seen) > 30) {
uwsgi_log_verbose("no presence announce in the last 30 seconds by node %s, i assume it is dead.\n", ucn->name);
ucn->name[0] = 0 ;
}
@@ -588,15 +639,23 @@ void master_loop(char **argv, char **environ) {
}
gettimeofday(&last_respawn, NULL);
uwsgi.respawn_delta = last_respawn.tv_sec;
// close the communication pipe
close(uwsgi.workers[uwsgi.mywid].pipe[0]);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.workers[uwsgi.mywid].pipe)) {
uwsgi_error("socketpair()\n");
continue;
}
pid = fork();
if (pid == 0) {
// fix the communication pipe
close(uwsgi.workers[uwsgi.mywid].pipe[0]);
uwsgi.mypid = getpid();
uwsgi.workers[uwsgi.mywid].pid = uwsgi.mypid;
uwsgi.workers[uwsgi.mywid].harakiri = 0;
uwsgi.workers[uwsgi.mywid].requests = 0;
uwsgi.workers[uwsgi.mywid].failed_requests = 0;
uwsgi.workers[uwsgi.mywid].respawn_count++;
uwsgi.workers[uwsgi.mywid].last_spawn = time(NULL);
uwsgi.workers[uwsgi.mywid].last_spawn = current_time;
uwsgi.workers[uwsgi.mywid].manage_next_request = 1;
break;
}
@@ -605,6 +664,8 @@ void master_loop(char **argv, char **environ) {
}
else {
uwsgi_log( "Respawned uWSGI worker (new pid: %d)\n", pid);
close(uwsgi.workers[uwsgi.mywid].pipe[1]);
uwsgi_signal_poll[uwsgi.mywid-1].fd = uwsgi.workers[uwsgi.mywid].pipe[0];
#ifdef UWSGI_SPOOLER
if (uwsgi.mywid <= 0 && diedpid != uwsgi.shared->spooler_pid) {
#else
+4
View File
@@ -645,6 +645,10 @@ void uwsgi_uwsgi_config(char *module) {
if (uwsgi.sharedareasize > 0 && uwsgi.sharedarea) {
init_uwsgi_module_sharedarea(new_uwsgi_module);
}
if (uwsgi.cache_max_items > 0) {
init_uwsgi_module_cache(new_uwsgi_module);
}
}
#endif
+110 -15
View File
@@ -7,17 +7,6 @@ char *spool_buffer = NULL;
extern struct uwsgi_server uwsgi;
extern struct uwsgi_python up;
#ifdef __APPLE__
#define UWSGI_LOCK OSSpinLockLock((OSSpinLock *) uwsgi.sharedareamutex);
#define UWSGI_UNLOCK OSSpinLockUnlock((OSSpinLock *) uwsgi.sharedareamutex);
#elif defined(__linux__) || defined(__sun__) || defined(__FreeBSD__)
#define UWSGI_LOCK pthread_mutex_lock((pthread_mutex_t *) uwsgi.sharedareamutex + sizeof(pthread_mutexattr_t));
#define UWSGI_UNLOCK pthread_mutex_unlock((pthread_mutex_t *) uwsgi.sharedareamutex + sizeof(pthread_mutexattr_t));
#else
#define UWSGI_LOCK if (flock(uwsgi.sockets[0].fd, LOCK_EX)) { uwsgi_error("flock()"); }
#define UWSGI_UNLOCK if (flock(uwsgi.sockets[0].fd, LOCK_UN)) { uwsgi_error("flock()"); }
#endif
#define UWSGI_LOGBASE "[- uWSGI -"
char *uwsgi_encode_pydict(PyObject *pydict, uint16_t *size) {
@@ -166,6 +155,22 @@ PyObject *py_uwsgi_close(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_signal(PyObject * self, PyObject * args) {
char uwsgi_signal;
if (!PyArg_ParseTuple(args, "B:signal", &uwsgi_signal)) {
return NULL;
}
uwsgi_log("sending %d to master\n", uwsgi_signal);
write(uwsgi.workers[uwsgi.mywid].pipe[1], &uwsgi_signal, 1);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_recv_frame(PyObject * self, PyObject * args) {
struct wsgi_request *wsgi_req = current_wsgi_req();
@@ -545,8 +550,8 @@ PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
#else
if (uwsgi.numproc > 1 && uwsgi.mypid != uwsgi.workers[0].pid) {
#endif
UWSGI_LOCK
UWSGI_SET_LOCKING;
uwsgi_lock(uwsgi.user_lock);
UWSGI_SET_LOCKING;
}
Py_INCREF(Py_None);
@@ -555,8 +560,8 @@ PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) {
PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) {
UWSGI_UNLOCK
UWSGI_UNSET_LOCKING;
uwsgi_unlock(uwsgi.user_lock);
UWSGI_UNSET_LOCKING;
Py_INCREF(Py_None);
return Py_None;
@@ -1766,6 +1771,8 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
{"send", py_uwsgi_send, METH_VARARGS, ""},
{"cl", py_uwsgi_cl, METH_VARARGS, ""},
{"signal", py_uwsgi_signal, METH_VARARGS, ""},
#ifdef UWSGI_SENDFILE
{"sendfile", py_uwsgi_advanced_sendfile, METH_VARARGS, ""},
#endif
@@ -1813,6 +1820,77 @@ static PyMethodDef uwsgi_sa_methods[] = {
{NULL, NULL},
};
PyObject *py_uwsgi_cache_del(PyObject * self, PyObject * args) {
char *key ;
char *value ;
if (!PyArg_ParseTuple(args, "s:cache_del", &key, &value)) {
return NULL;
}
if (uwsgi_cache_del(key, strlen(key))) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_cache_set(PyObject * self, PyObject * args) {
char *key ;
char *value ;
uint64_t expires = 0;
if (!PyArg_ParseTuple(args, "ss|i:cache_set", &key, &value, &expires)) {
return NULL;
}
if (uwsgi_cache_set(key, strlen(key), value, strlen(value), expires)) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(Py_True);
return Py_True;
}
PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
char *key ;
uint16_t valsize;
char *value ;
if (!PyArg_ParseTuple(args, "s:cache_get", &key)) {
return NULL;
}
value = uwsgi_cache_get(key, strlen(key), &valsize);
if (value) {
return PyString_FromStringAndSize(value, valsize);
}
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef uwsgi_cache_methods[] = {
{"cache_get", py_uwsgi_cache_get, METH_VARARGS, ""},
{"cache_set", py_uwsgi_cache_set, METH_VARARGS, ""},
{"cache_del", py_uwsgi_cache_del, METH_VARARGS, ""},
{NULL, NULL},
};
#ifdef UWSGI_SPOOLER
@@ -1865,6 +1943,23 @@ void init_uwsgi_module_advanced(PyObject * current_uwsgi_module) {
}
void init_uwsgi_module_cache(PyObject * current_uwsgi_module) {
PyMethodDef *uwsgi_function;
PyObject *uwsgi_module_dict;
uwsgi_module_dict = PyModule_GetDict(current_uwsgi_module);
if (!uwsgi_module_dict) {
uwsgi_log( "could not get uwsgi module __dict__\n");
exit(1);
}
for (uwsgi_function = uwsgi_cache_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
PyDict_SetItemString(uwsgi_module_dict, uwsgi_function->ml_name, func);
Py_DECREF(func);
}
}
void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) {
PyMethodDef *uwsgi_function;
PyObject *uwsgi_module_dict;
+1
View File
@@ -195,5 +195,6 @@ void gil_fake_release(void);
void init_uwsgi_module_advanced(PyObject *);
void init_uwsgi_module_spooler(PyObject *);
void init_uwsgi_module_sharedarea(PyObject *);
void init_uwsgi_module_cache(PyObject *);
PyObject *uwsgi_pyimport_by_filename(char *, char *);
-1
View File
@@ -15,7 +15,6 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
}
*/
wsgi_socket = PyFile_FromFile(wsgi_req->async_post, "wsgi_input", "r", NULL);
PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", wsgi_socket);
Py_DECREF(wsgi_socket);
+1
View File
@@ -401,6 +401,7 @@ void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id) {
wsgi_req->post_buffering_buf = uwsgi.async_post_buf[wsgi_req->async_id];
}
}
int wsgi_req_recv(struct wsgi_request *wsgi_req) {
+47 -25
View File
@@ -58,6 +58,7 @@ static struct option long_base_options[] = {
{"max-requests", required_argument, 0, 'R'},
{"socket-timeout", required_argument, 0, 'z'},
{"sharedarea", required_argument, 0, 'A'},
{"cache", required_argument, 0, LONG_ARGS_CACHE},
#ifdef UWSGI_SPOOLER
{"spooler", required_argument, 0, 'Q'},
#endif
@@ -861,40 +862,24 @@ options_parsed:
}
}
uwsgi.user_lock = uwsgi_mmap_shared_lock();
if (!uwsgi.user_lock) {
uwsgi_error("mmap()");
exit(1);
}
uwsgi_lock_init(uwsgi.user_lock);
#ifdef UWSGI_EMBEDDED
if (uwsgi.sharedareasize > 0) {
#ifndef __OpenBSD__
uwsgi.sharedareamutex = mmap(NULL, sizeof(pthread_mutexattr_t) + sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
uwsgi.sharedareamutex = uwsgi_mmap_shared_lock();
if (!uwsgi.sharedareamutex) {
uwsgi_error("mmap()");
exit(1);
}
#else
uwsgi_log("***WARNING*** the sharedarea on OpenBSD is not SMP-safe. Beware of race conditions !!!\n");
#endif
uwsgi.sharedarea = mmap(NULL, uwsgi.page_size * uwsgi.sharedareasize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (uwsgi.sharedarea) {
uwsgi_log("shared area mapped at %p, you can access it with uwsgi.sharedarea* functions.\n", uwsgi.sharedarea);
#ifdef __APPLE__
memset(uwsgi.sharedareamutex, 0, sizeof(OSSpinLock));
#else
#if !defined(__OpenBSD__) && !defined(__NetBSD__)
if (pthread_mutexattr_init((pthread_mutexattr_t *) uwsgi.sharedareamutex)) {
uwsgi_log("unable to allocate mutexattr structure\n");
exit(1);
}
if (pthread_mutexattr_setpshared((pthread_mutexattr_t *) uwsgi.sharedareamutex, PTHREAD_PROCESS_SHARED)) {
uwsgi_log("unable to share mutex\n");
exit(1);
}
if (pthread_mutex_init((pthread_mutex_t *) uwsgi.sharedareamutex + sizeof(pthread_mutexattr_t), (pthread_mutexattr_t *) uwsgi.sharedareamutex)) {
uwsgi_log("unable to initialize mutex\n");
exit(1);
}
#endif
#endif
uwsgi_lock_init(uwsgi.sharedareamutex);
} else {
uwsgi_error("mmap()");
exit(1);
@@ -903,6 +888,33 @@ options_parsed:
}
#endif
if (uwsgi.cache_max_items > 0) {
uwsgi.cache_items = mmap(NULL, sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!uwsgi.cache_items) {
uwsgi_error("mmap()");
exit(1);
}
uwsgi.cache = mmap(NULL, 32768 * uwsgi.cache_max_items, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (!uwsgi.cache) {
uwsgi_error("mmap()");
exit(1);
}
for(i=0;i<uwsgi.cache_max_items;i++) {
memset(&uwsgi.cache_items[i], 0, sizeof(struct uwsgi_cache_item));
}
// the first cache item is always zero
uwsgi.shared->cache_first_available_item = 1;
uwsgi.cache_lock = uwsgi_mmap_shared_lock();
if (!uwsgi.cache_lock) {
uwsgi_error("mmap()");
exit(1);
}
uwsgi_lock_init(uwsgi.cache_lock);
}
uwsgi.current_wsgi_req = simple_current_wsgi_req;
@@ -1298,8 +1310,14 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
uwsgi.respawn_delta = last_respawn.tv_sec;
}
for (i = 2 - uwsgi.master_process; i < uwsgi.numproc + 1; i++) {
// setup internal signalling system
if (socketpair(AF_UNIX, SOCK_STREAM, 0, uwsgi.workers[i].pipe)) {
uwsgi_error("socketpair()\n");
exit(1);
}
pid = fork();
if (pid == 0) {
close(uwsgi.workers[i].pipe[0]);
uwsgi.mypid = getpid();
uwsgi.workers[i].pid = uwsgi.mypid;
uwsgi.workers[i].id = i;
@@ -1312,6 +1330,7 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100
exit(1);
} else {
uwsgi_log("spawned uWSGI worker %d (pid: %d, cores: %d)\n", i, pid, uwsgi.cores);
close(uwsgi.workers[i].pipe[1]);
gettimeofday(&last_respawn, NULL);
uwsgi.respawn_delta = last_respawn.tv_sec;
}
@@ -1772,6 +1791,9 @@ end:
case LONG_ARGS_CHECK_INTERVAL:
uwsgi.shared->options[UWSGI_OPTION_MASTER_INTERVAL] = atoi(optarg);
return 1;
case LONG_ARGS_CACHE:
uwsgi.cache_max_items = atoi(optarg);
return 1;
case 'A':
uwsgi.sharedareasize = atoi(optarg);
return 1;
+45
View File
@@ -173,6 +173,27 @@
#define UWSGI_LISTEN_QUEUE 511
#endif
#define UWSGI_CACHE_MAX_KEY_SIZE 4071
// maintain alignment here !!!
struct uwsgi_cache_item {
// size of the key
uint16_t keysize;
// djb hash of the key
uint32_t djbhash;
// size of the value (max 64KB)
uint16_t valsize;
// 64bit expiration (0 for immortal)
uint64_t expires;
// 64bit hits
uint64_t hits;
// mark the end of the table
char used;
// key chracters follows...
char key[UWSGI_CACHE_MAX_KEY_SIZE];
} __attribute__((__packed__));
struct uwsgi_opt {
char *key;
char *value;
@@ -244,6 +265,7 @@ struct uwsgi_opt {
#define LONG_ARGS_CLUSTER 17062
#define LONG_ARGS_CLUSTER_RELOAD 17063
#define LONG_ARGS_CLUSTER_LOG 17064
#define LONG_ARGS_CACHE 17065
@@ -809,6 +831,13 @@ struct uwsgi_server {
char *cluster;
int cluster_fd;
struct sockaddr_in mc_cluster_addr;
uint16_t cache_max_items;
struct uwsgi_cache_item *cache_items;
void *cache;
void *cache_lock;
void *user_lock;
};
#define CLUSTER_NODE_STATIC 0
@@ -875,6 +904,9 @@ struct uwsgi_shared {
#endif
uint16_t cache_first_available_item;
uint16_t cache_first_available_item_tmp;
};
struct uwsgi_core {
@@ -913,6 +945,9 @@ struct uwsgi_worker {
int manage_next_request;
// this is used for the internal signalling system
int pipe[2];
struct uwsgi_core **cores;
};
@@ -1191,3 +1226,13 @@ char *generate_socket_name(char *);
ssize_t uwsgi_send_message(int, uint8_t, uint8_t, char *, uint16_t, int, size_t, int);
char *uwsgi_cluster_best_node(void);
int uwsgi_cache_set(char *, uint16_t, char *, uint16_t, uint64_t);
int uwsgi_cache_del(char *, uint16_t);
char *uwsgi_cache_get(char *, uint16_t, uint16_t *);
#define uwsgi_mmap_shared_lock() mmap(NULL, sizeof(pthread_mutexattr_t) + sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0)
void uwsgi_lock_init(void *);
void uwsgi_lock(void *);
void uwsgi_unlock(void *);
+22 -2
View File
@@ -136,7 +136,7 @@ class uConf():
def __init__(self, filename):
self.config = ConfigParser.ConfigParser()
self.config.read(filename)
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'plugins', 'loop', 'uwsgi']
self.gcc_list = ['utils', 'protocol', 'socket', 'logging', 'master', 'plugins', 'lock', 'cache', 'loop', 'uwsgi']
self.cflags = ['-O2', '-Wall', '-Werror', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] + os.environ.get("CFLAGS", "").split()
gcc_version = str(spcall2("%s -v" % GCC)).split('\n')[-1].split()[2]
gcc_major = int(gcc_version.split('.')[0])
@@ -153,13 +153,15 @@ class uConf():
def set(self, key, value):
self.config.set('uwsgi',key, value)
def get(self,key):
def get(self,key,default=None):
try:
value = self.config.get('uwsgi', key)
if value == "" or value == "false":
return None
return value
except:
if default:
return default
return None
def depends_on(self, what, dep):
@@ -186,6 +188,24 @@ class uConf():
self.libs.remove('-lpthread')
self.libs.append('-lroot')
# set locking subsystem
locking_mode = self.get('locking','auto')
print locking_mode, uwsgi_os
if locking_mode == 'auto':
if uwsgi_os == 'Linux':
locking_mode = 'pthread_mutex'
elif uwsgi_os == 'Darwin':
locking_mode = 'osx_spinlock'
if locking_mode == 'pthread_mutex':
self.cflags.append('-DUWSGI_LOCK_USE_MUTEX')
elif locking_mode == 'osx_spinlock':
self.cflags.append('-DUWSGI_LOCK_USE_OSX_SPINLOCK')
else:
self.cflags.append('-DUWSGI_LOCK_USE_FLOCK')
if self.get('embedded'):
self.cflags.append('-DUWSGI_EMBEDDED')
+1
View File
@@ -48,6 +48,7 @@ def application(e, start_response):
message = uwsgi.recv_frame(client, '\x00', '\xff')
while message:
print message
uwsgi.signal(-17)
yield '\x00' + message + '\xff'
if len(message) == 0:
raise StopIteration