diff --git a/cache.c b/cache.c
index 62096cb3..ac8858ec 100644
--- a/cache.c
+++ b/cache.c
@@ -174,18 +174,28 @@ end:
}
-void cache_command(char *key, uint16_t keylen, char *val, uint64_t vallen, void *data) {
+void cache_command(char *key, uint16_t keylen, char *val, uint16_t vallen, void *data) {
struct wsgi_request *wsgi_req = (struct wsgi_request *) data;
+ uint64_t tmp_vallen = 0;
if (vallen > 0) {
if (!uwsgi_strncmp(key, keylen, "key", 3)) {
- val = uwsgi_cache_get(val, vallen, &vallen);
- if (val && vallen > 0) {
+ val = uwsgi_cache_get(val, vallen, &tmp_vallen);
+ if (val && tmp_vallen > 0) {
wsgi_req->response_size = write(wsgi_req->poll.fd, val, vallen);
}
}
+ else if (!uwsgi_strncmp(key, keylen, "get", 3)) {
+ val = uwsgi_cache_get(val, vallen, &tmp_vallen);
+ if (val && vallen > 0) {
+ wsgi_req->response_size = write(wsgi_req->poll.fd, val, tmp_vallen);
+ }
+ else {
+ wsgi_req->response_size = write(wsgi_req->poll.fd, "HTTP/1.0 404 Not Found\r\n\r\n
Not Found
", 44);
+ }
+ }
}
}
@@ -228,7 +238,7 @@ int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
case 4:
// dict
if (wsgi_req->uh.pktsize > 0) {
- //uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh.pktsize, cache_command, (void *) wsgi_req);
+ uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh.pktsize, cache_command, (void *) wsgi_req);
}
break;
}
diff --git a/lock.c b/lock.c
index e75fcfce..e2e27274 100644
--- a/lock.c
+++ b/lock.c
@@ -4,6 +4,7 @@
#ifdef UWSGI_LOCK_USE_MUTEX
#define UWSGI_LOCK_SIZE sizeof(pthread_mutexattr_t) + sizeof(pthread_mutex_t)
+#define UWSGI_RWLOCK_SIZE sizeof(pthread_rwlockattr_t) + sizeof(pthread_rwlock_t)
// REMEMBER lock must contains space for both pthread_mutex_t and pthread_mutexattr_t !!!
void uwsgi_lock_init(void *lock) {
@@ -25,6 +26,18 @@ void uwsgi_lock_init(void *lock) {
}
+void uwsgi_rlock(void *lock) {
+ pthread_rwlock_rdlock((pthread_rwlock_t *) lock + sizeof(pthread_rwlockattr_t));
+}
+
+void uwsgi_wlock(void *lock) {
+ pthread_rwlock_wrlock((pthread_rwlock_t *) lock + sizeof(pthread_rwlockattr_t));
+}
+
+void uwsgi_rwunlock(void *lock) {
+ pthread_rwlock_unlock((pthread_rwlock_t *) lock + sizeof(pthread_rwlockattr_t));
+}
+
void uwsgi_lock(void *lock) {
pthread_mutex_lock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t));
@@ -35,6 +48,26 @@ void uwsgi_unlock(void *lock) {
pthread_mutex_unlock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t));
}
+void uwsgi_rwlock_init(void *lock) {
+
+ if (pthread_rwlockattr_init((pthread_rwlockattr_t *) lock)) {
+ uwsgi_log("unable to allocate rwlock structure\n");
+ exit(1);
+ }
+ if (pthread_rwlockattr_setpshared((pthread_rwlockattr_t *) lock, PTHREAD_PROCESS_SHARED)) {
+ uwsgi_log("unable to share rwlock\n");
+ exit(1);
+ }
+
+ if (pthread_rwlock_init((pthread_rwlock_t *) lock + sizeof(pthread_rwlockattr_t), (pthread_rwlockattr_t *) lock)) {
+ uwsgi_log("unable to initialize rwlock\n");
+ exit(1);
+ }
+
+
+}
+
+
#endif
@@ -43,7 +76,13 @@ void uwsgi_unlock(void *lock) {
#include
#include
-#define UWSGI_LOCK_SIZE sizeof(struct umtx)
+#define UWSGI_LOCK_SIZE sizeof(struct umtx)
+#define UWSGI_RWLOCK_SIZE sizeof(struct umtx)
+
+#define uwsgi_rwlock_init uwsgi_lock_init
+#define uwsgi_rlock uwsgi_lock
+#define uwsgi_wlock uwsgi_lock
+#define uwsgi_rwunlock uwsgi_lock
void uwsgi_lock_init(void *lock) {
umtx_init((struct umtx*) lock);
@@ -62,7 +101,13 @@ void uwsgi_unlock(void *lock) {
#ifdef UWSGI_LOCK_USE_OSX_SPINLOCK
-#define UWSGI_LOCK_SIZE sizeof(OSSpinLock)
+#define UWSGI_LOCK_SIZE sizeof(OSSpinLock)
+#define UWSGI_RWLOCK_SIZE sizeof(OSSpinLock)
+
+#define uwsgi_rwlock_init uwsgi_lock_init
+#define uwsgi_rlock uwsgi_lock
+#define uwsgi_wlock uwsgi_lock
+#define uwsgi_rwunlock uwsgi_lock
void uwsgi_lock_init(void *lock) {
@@ -109,3 +154,15 @@ void *uwsgi_mmap_shared_lock() {
return addr;
}
+
+void *uwsgi_mmap_shared_rwlock() {
+ void *addr = NULL;
+ addr = mmap(NULL, UWSGI_RWLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+
+ if (addr == NULL) {
+ uwsgi_error("mmap()");
+ exit(1);
+ }
+
+ return addr;
+}
diff --git a/master.c b/master.c
index 57d169cc..cec2b9b0 100644
--- a/master.c
+++ b/master.c
@@ -584,13 +584,13 @@ void master_loop(char **argv, char **environ) {
// remove expired cache items
if (uwsgi.cache_max_items > 0) {
for(i=0;i< (int)uwsgi.cache_max_items;i++) {
- uwsgi_lock(uwsgi.cache_lock);
+ uwsgi_wlock(uwsgi.cache_lock);
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);
}
}
- uwsgi_unlock(uwsgi.cache_lock);
+ uwsgi_rwunlock(uwsgi.cache_lock);
}
}
diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c
index b23ff8d7..c9c7efb9 100644
--- a/plugins/python/uwsgi_pymodule.c
+++ b/plugins/python/uwsgi_pymodule.c
@@ -2368,13 +2368,13 @@ PyObject *py_uwsgi_cache_del(PyObject * self, PyObject * args) {
uwsgi_simple_send_string(remote, 111, 2, key, keylen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
}
else if (uwsgi.cache_max_items) {
- uwsgi_lock(uwsgi.cache_lock);
+ uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi_cache_del(key, strlen(key))) {
- uwsgi_unlock(uwsgi.cache_lock);
+ uwsgi_rwunlock(uwsgi.cache_lock);
Py_INCREF(Py_None);
return Py_None;
}
- uwsgi_unlock(uwsgi.cache_lock);
+ uwsgi_rwunlock(uwsgi.cache_lock);
}
Py_INCREF(Py_True);
@@ -2405,13 +2405,13 @@ PyObject *py_uwsgi_cache_set(PyObject * self, PyObject * args) {
uwsgi_simple_send_string2(remote, 111, 1, key, keylen, value, vallen, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
}
else if (uwsgi.cache_max_items) {
- uwsgi_lock(uwsgi.cache_lock);
+ uwsgi_wlock(uwsgi.cache_lock);
if (uwsgi_cache_set(key, keylen, value, vallen, expires)) {
- uwsgi_unlock(uwsgi.cache_lock);
+ uwsgi_rwunlock(uwsgi.cache_lock);
Py_INCREF(Py_None);
return Py_None;
}
- uwsgi_unlock(uwsgi.cache_lock);
+ uwsgi_rwunlock(uwsgi.cache_lock);
}
Py_INCREF(Py_True);
@@ -2478,7 +2478,7 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
#ifdef UWSGI_DEBUG
gettimeofday(&tv, NULL);
#endif
- uwsgi_lock(uwsgi.cache_lock);
+ uwsgi_rlock(uwsgi.cache_lock);
value = uwsgi_cache_get(key, keylen, &valsize);
res = PyString_FromStringAndSize(value, valsize);
#ifdef UWSGI_DEBUG
@@ -2487,7 +2487,7 @@ PyObject *py_uwsgi_cache_get(PyObject * self, PyObject * args) {
uwsgi_log("[slow] cache get done in %d microseconds (%llu bytes value)\n", (tv2.tv_sec* (1000*1000) + tv2.tv_usec) - (tv.tv_sec* (1000*1000) + tv.tv_usec), (unsigned long long) valsize);
}
#endif
- uwsgi_unlock(uwsgi.cache_lock);
+ uwsgi_rwunlock(uwsgi.cache_lock);
return res;
}
diff --git a/uwsgi.c b/uwsgi.c
index 55f599d8..dddc3210 100644
--- a/uwsgi.c
+++ b/uwsgi.c
@@ -1106,8 +1106,8 @@ int uwsgi_start(void *v_argv) {
uwsgi.shared->cache_first_available_item = 1;
uwsgi.shared->cache_unused_stack_ptr = 0;
- uwsgi.cache_lock = uwsgi_mmap_shared_lock();
- uwsgi_lock_init(uwsgi.cache_lock);
+ uwsgi.cache_lock = uwsgi_mmap_shared_rwlock();
+ uwsgi_rwlock_init(uwsgi.cache_lock);
uwsgi.p[111] = &uwsgi_cache_plugin;
diff --git a/uwsgi.h b/uwsgi.h
index cdcb3a1a..82106578 100644
--- a/uwsgi.h
+++ b/uwsgi.h
@@ -1346,6 +1346,11 @@ void uwsgi_lock_init(void *);
void uwsgi_lock(void *);
void uwsgi_unlock(void *);
+void uwsgi_rwlock_init(void *);
+void uwsgi_rlock(void *);
+void uwsgi_wlock(void *);
+void uwsgi_rwunlock(void *);
+
inline void *uwsgi_malloc(size_t);
@@ -1367,6 +1372,7 @@ struct uwsgi_fmon *event_queue_ack_file_monitor(int, int);
void *uwsgi_mmap_shared_lock(void);
+void *uwsgi_mmap_shared_rwlock(void);
void uwsgi_register_signal(uint8_t, uint8_t, void *, uint8_t, char *, uint8_t);
void uwsgi_register_file_monitor(uint8_t, char *, uint8_t, void *, uint8_t);