summaryrefslogtreecommitdiff
path: root/extra
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2010-10-19 17:10:01 +0200
committerPieter Noordhuis <pcnoordhuis@gmail.com>2010-10-19 21:24:24 +0200
commite245ab48ec8f766e589771b976761a0a41b6442d (patch)
treea1412036f29a8d6fce9a0e1f08aa5c2c8ebd6596 /extra
parent206868de060bbfeb2745dad2f410691ad2fc62f8 (diff)
Added header file and example for usage from libev
Diffstat (limited to 'extra')
-rw-r--r--extra/hiredis/libev.h90
1 files changed, 90 insertions, 0 deletions
diff --git a/extra/hiredis/libev.h b/extra/hiredis/libev.h
new file mode 100644
index 0000000..79dde42
--- /dev/null
+++ b/extra/hiredis/libev.h
@@ -0,0 +1,90 @@
+#include <sys/types.h>
+#include <ev.h>
+#include <hiredis.h>
+
+/* Prototype for the error callback. */
+typedef void (redisErrorCallback)(const redisContext*);
+
+typedef struct libevRedisEvents {
+ redisContext *context;
+ redisErrorCallback *err;
+ struct ev_loop *loop;
+ ev_io rev, wev;
+} libevRedisEvents;
+
+void libevRedisReadEvent(struct ev_loop *loop, ev_io *watcher, int revents) {
+ ((void)loop); ((void)revents);
+ libevRedisEvents *e = watcher->data;
+
+ if (redisBufferRead(e->context) == REDIS_ERR) {
+ e->err(e->context);
+ } else {
+ if (redisProcessCallbacks(e->context) == REDIS_ERR) {
+ e->err(e->context);
+ }
+ }
+}
+
+void libevRedisWriteEvent(struct ev_loop *loop, ev_io *watcher, int revents) {
+ ((void)loop); ((void)revents);
+ libevRedisEvents *e = watcher->data;
+ int done = 0;
+
+ if (redisBufferWrite(e->context, &done) == REDIS_ERR) {
+ ev_io_stop(e->loop,&e->wev);
+ e->err(e->context);
+ } else {
+ /* Stop firing the write event when done */
+ if (done) {
+ ev_io_stop(e->loop,&e->wev);
+ ev_io_start(e->loop,&e->rev);
+ }
+ }
+}
+
+void libevRedisCommandCallback(redisContext *c, void *privdata) {
+ ((void)c);
+ libevRedisEvents *e = privdata;
+ ev_io_start(e->loop,&e->wev);
+}
+
+void libevRedisDisconnectCallback(redisContext *c, void *privdata) {
+ ((void)c);
+ libevRedisEvents *e = privdata;
+ ev_io_stop(e->loop,&e->rev);
+ ev_io_stop(e->loop,&e->wev);
+}
+
+void libevRedisFreeCallback(redisContext *c, void *privdata) {
+ ((void)c);
+ libevRedisEvents *e = privdata;
+ free(e);
+}
+
+redisContext *libevRedisConnect(struct ev_loop *loop, redisErrorCallback *err, const char *ip, int port) {
+ libevRedisEvents *e;
+ redisContext *c = redisConnectNonBlock(ip, port, NULL);
+ if (c->error != NULL) {
+ err(c);
+ redisFree(c);
+ return NULL;
+ }
+
+ /* Create container for context and r/w events */
+ e = malloc(sizeof(*e));
+ e->loop = loop;
+ e->context = c;
+ e->err = err;
+ e->rev.data = e;
+ e->wev.data = e;
+
+ /* Register callbacks */
+ redisSetDisconnectCallback(c,libevRedisDisconnectCallback,e);
+ redisSetCommandCallback(c,libevRedisCommandCallback,e);
+ redisSetFreeCallback(c,libevRedisFreeCallback,e);
+
+ /* Initialize read/write events */
+ ev_io_init(&e->rev,libevRedisReadEvent,c->fd,EV_READ);
+ ev_io_init(&e->wev,libevRedisWriteEvent,c->fd,EV_WRITE);
+ return c;
+}