diff options
Diffstat (limited to 'adapters')
-rw-r--r-- | adapters/libuv.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/adapters/libuv.h b/adapters/libuv.h new file mode 100644 index 0000000..e61d5ca --- /dev/null +++ b/adapters/libuv.h @@ -0,0 +1,120 @@ +#ifndef __HIREDIS_LIBUV_H__ +#define __HIREDIS_LIBUV_H__ +#include <uv.h> +#include "../hiredis.h" +#include "../async.h" + + +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 |