summaryrefslogtreecommitdiff
path: root/core/sharedarea.c
diff options
context:
space:
mode:
authorRoberto De Ioris <info@unbit.it>2013-11-29 07:46:28 +0100
committerRoberto De Ioris <info@unbit.it>2013-11-29 07:46:28 +0100
commit082d47e15647c1e56aece6abd5f39e8d9571a481 (patch)
tree57838e8da660edc85e30b5f1ebbcda45af0caaac /core/sharedarea.c
parent0715031b0068695574ebae1596e6efa300cf1fd0 (diff)
downloaduwsgi-082d47e15647c1e56aece6abd5f39e8d9571a481.tar.gz
area is a better field name for sharedarea
Diffstat (limited to 'core/sharedarea.c')
-rw-r--r--core/sharedarea.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/core/sharedarea.c b/core/sharedarea.c
new file mode 100644
index 00000000..ca75bf3a
--- /dev/null
+++ b/core/sharedarea.c
@@ -0,0 +1,118 @@
+#include <uwsgi.h>
+
+extern struct uwsgi_server uwsgi;
+
+/*
+
+This is an high-performance memory area shared by all workers/cores/threads
+
+Contrary to the caching subsystem it is 1-copy (caching for non-c apps is 2-copy)
+
+Languages not allowing that kind of access should emulate it calling uwsgi_malloc and then copying it back to
+the language object.
+
+The memory areas could be monitored for changes (read: cores can be suspended while waiting for values)
+
+You can configure multiple areas specifying multiple --sharedarea options
+
+This is a very low-level api, try to use it to build higher-level primitives or rely on the caching subsystem
+
+*/
+
+struct uwsgi_sharedarea *uwsgi_sharedarea_get_by_id(int id, uint64_t pos) {
+ if (id > uwsgi.sharedareas_cnt-1) return NULL;
+ struct uwsgi_sharedarea *sa = uwsgi.sharedareas[id];
+ if (pos > sa->max_pos) return NULL;
+ return sa;
+}
+
+int uwsgi_sharedarea_read(int id, uint64_t pos, char *blob, uint64_t len) {
+ return -1;
+}
+
+int uwsgi_sharedarea_write(int id, uint64_t pos, char *blob, uint64_t len) {
+ return -1;
+}
+
+int uwsgi_sharedarea_read64(int id, uint64_t pos, int64_t *value) {
+ return -1;
+}
+
+int uwsgi_sharedarea_write64(int id, uint64_t pos, int64_t value) {
+ return -1;
+}
+
+/*
+ returns:
+ 0 -> on updates
+ -1 -> on error
+ -2 -> on timeout
+*/
+int uwsgi_sharedarea_wait(int id, int freq, int timeout) {
+ int waiting = 0;
+ struct uwsgi_sharedarea *sa = uwsgi_sharedarea_get_by_id(id, 0);
+ if (!sa) return -1;
+ uwsgi_rlock(sa->lock);
+ uint64_t updates = sa->updates;
+ uwsgi_rwunlock(sa->lock);
+ while(timeout == 0 || (timeout > 0 && (waiting/1000) >= timeout)) {
+ uwsgi.wait_milliseconds_hook(freq);
+ waiting += freq;
+ // lock sa
+ uwsgi_rlock(sa->lock);
+ if (sa->updates != updates) return 0;
+ // unlock sa
+ uwsgi_rwunlock(sa->lock);
+ }
+ return -2;
+}
+
+struct uwsgi_sharedarea *uwsgi_sharedarea_init(int id, int pages) {
+ uwsgi.sharedareas[id] = uwsgi_calloc_shared(uwsgi.page_size * (pages + 1));
+ uwsgi.sharedareas[id]->area = ((char *) uwsgi.sharedareas[id]) + uwsgi.page_size;
+ uwsgi.sharedareas[id]->id = id;
+ uwsgi.sharedareas[id]->fd = -1;
+ uwsgi.sharedareas[id]->pages = pages;
+ uwsgi.sharedareas[id]->max_pos = (uwsgi.page_size * pages) -1;
+ char *id_str = uwsgi_num2str(id);
+ uwsgi.sharedareas[id]->lock = uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
+ free(id_str);
+ return uwsgi.sharedareas[id];
+}
+
+struct uwsgi_sharedarea *uwsgi_sharedarea_init_keyval(int id, char *arg) {
+ char *s_pages = NULL;
+ char *s_file = NULL;
+ char *s_fd = NULL;
+ char *s_size = NULL;
+ if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=',
+ "pages", &s_pages,
+ "file", &s_file,
+ "fd", &s_fd,
+ "size", &s_size,
+ NULL)) {
+ }
+
+ return NULL;
+}
+
+
+void uwsgi_sharedareas_init() {
+ struct uwsgi_string_list *usl = NULL;
+ uwsgi_foreach(usl, uwsgi.sharedareas_list) {
+ uwsgi.sharedareas_cnt++;
+ }
+ uwsgi.sharedareas = uwsgi_calloc(sizeof(struct uwsgi_sharedarea *) * uwsgi.sharedareas_cnt);
+ int id = 0;
+ uwsgi_foreach(usl, uwsgi.sharedareas_list) {
+ char *is_keyval = strchr(usl->value, '=');
+ struct uwsgi_sharedarea *sa = NULL;
+ if (!is_keyval) {
+ sa = uwsgi_sharedarea_init(id, atoi(usl->value));
+ }
+ else {
+ sa = uwsgi_sharedarea_init_keyval(id, usl->value);
+ }
+ id++;
+ }
+}