123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- #ifndef __HIREDIS_LIBUV_H__
- #define __HIREDIS_LIBUV_H__
- #include <stdlib.h>
- #include <uv.h>
- #include "../hiredis.h"
- #include "../async.h"
- #include <string.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 (p->context != NULL && (events & UV_READABLE)) {
- redisAsyncHandleRead(p->context);
- }
- if (p->context != NULL && (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;
- p->context = NULL; // indicate that context might no longer exist
- uv_close((uv_handle_t*)&p->handle, on_close);
- }
- static 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 = (redisLibuvEvents*)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
|