summaryrefslogtreecommitdiff
path: root/adapters/libuv.h
diff options
context:
space:
mode:
authorErik Dubbelboer <erik@dubbelboer.com>2013-06-04 15:06:43 +0200
committerErik Dubbelboer <erik@dubbelboer.com>2013-06-04 15:06:43 +0200
commit61277d09251cfef4f768ea5d263145248e2c3a83 (patch)
tree78f4886d8fd5ea459bd4b7c34cd123614f1577e1 /adapters/libuv.h
parentbcf83543762577a9b0f5625c848b7061cc980f30 (diff)
Added libuv adapter
Diffstat (limited to 'adapters/libuv.h')
-rw-r--r--adapters/libuv.h123
1 files changed, 123 insertions, 0 deletions
diff --git a/adapters/libuv.h b/adapters/libuv.h
new file mode 100644
index 0000000..63bec63
--- /dev/null
+++ b/adapters/libuv.h
@@ -0,0 +1,123 @@
+#ifndef __HIREDIS_LIBUV_H__
+#define __HIREDIS_LIBUV_H__
+#include <uv.h>
+#include "../hiredis.h"
+#include "../async.h"
+//#include <stdlib.h> // malloc(), free()
+//#include <string.h> // memset()
+//#include <assert.h> // assert()
+
+
+typedef struct redisLibuvEvents {
+ redisAsyncContext* context;
+ uv_poll_t handle;
+ int events;
+} redisLibuvEvents;
+
+
+static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
+ redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
+
+ if (status != 0) {
+ return;
+ }
+
+ if (events & UV_READABLE) {
+ redisAsyncHandleRead(p->context);
+ }
+ if (events & UV_WRITABLE) {
+ redisAsyncHandleWrite(p->context);
+ }
+}
+
+
+static void redisLibuvAddRead(void *privdata) {
+ redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+ p->events |= UV_READABLE;
+
+ uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+}
+
+
+static void redisLibuvDelRead(void *privdata) {
+ redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+ p->events &= ~UV_READABLE;
+
+ if (p->events) {
+ uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+ } else {
+ uv_poll_stop(&p->handle);
+ }
+}
+
+
+static void redisLibuvAddWrite(void *privdata) {
+ redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+ p->events |= UV_WRITABLE;
+
+ uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+}
+
+
+static void redisLibuvDelWrite(void *privdata) {
+ redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+ p->events &= ~UV_WRITABLE;
+
+ if (p->events) {
+ uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+ } else {
+ uv_poll_stop(&p->handle);
+ }
+}
+
+
+static void on_close(uv_handle_t* handle) {
+ redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
+
+ free(p);
+}
+
+
+static void redisLibuvCleanup(void *privdata) {
+ redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+ uv_close((uv_handle_t*)&p->handle, on_close);
+}
+
+
+int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
+ redisContext *c = &(ac->c);
+
+ if (ac->ev.data != NULL) {
+ return REDIS_ERR;
+ }
+
+ ac->ev.addRead = redisLibuvAddRead;
+ ac->ev.delRead = redisLibuvDelRead;
+ ac->ev.addWrite = redisLibuvAddWrite;
+ ac->ev.delWrite = redisLibuvDelWrite;
+ ac->ev.cleanup = redisLibuvCleanup;
+
+ redisLibuvEvents* p = malloc(sizeof(*p));
+
+ if (!p) {
+ return REDIS_ERR;
+ }
+
+ memset(p, 0, sizeof(*p));
+
+ if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
+ return REDIS_ERR;
+ }
+
+ ac->ev.data = p;
+ p->handle.data = p;
+ p->context = ac;
+
+ return REDIS_OK;
+}
+#endif