Add adapter for the Redis-bundled ae event library
This commit is contained in:
parent
8322162e52
commit
9af1574d6e
9
Makefile
9
Makefile
@ -64,6 +64,15 @@ hiredis-example-libevent: example-libevent.c adapters/libevent.h ${DYLIBNAME}
|
|||||||
hiredis-example-libev: example-libev.c adapters/libev.h ${DYLIBNAME}
|
hiredis-example-libev: example-libev.c adapters/libev.h ${DYLIBNAME}
|
||||||
$(CC) -o $@ $(CCOPT) $(DEBUG) -L. -lhiredis -lev -Wl,-rpath,. example-libev.c
|
$(CC) -o $@ $(CCOPT) $(DEBUG) -L. -lhiredis -lev -Wl,-rpath,. example-libev.c
|
||||||
|
|
||||||
|
ifndef AE_DIR
|
||||||
|
hiredis-example-ae:
|
||||||
|
@echo "Please specify AE_DIR (e.g. <redis repository>/src)"
|
||||||
|
@false
|
||||||
|
else
|
||||||
|
hiredis-example-ae: example-ae.c adapters/ae.h ${DYLIBNAME}
|
||||||
|
$(CC) -o $@ $(CCOPT) $(DEBUG) -I$(AE_DIR) -L. -lhiredis -Wl,-rpath,. example-ae.c $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o
|
||||||
|
endif
|
||||||
|
|
||||||
hiredis-%: %.o ${DYLIBNAME}
|
hiredis-%: %.o ${DYLIBNAME}
|
||||||
$(CC) -o $@ $(CCOPT) $(DEBUG) -L. -lhiredis -Wl,-rpath,. $<
|
$(CC) -o $@ $(CCOPT) $(DEBUG) -L. -lhiredis -Wl,-rpath,. $<
|
||||||
|
|
||||||
|
95
adapters/ae.h
Normal file
95
adapters/ae.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
#include <ae.h>
|
||||||
|
#include "../hiredis.h"
|
||||||
|
#include "../async.h"
|
||||||
|
|
||||||
|
typedef struct redisAeEvents {
|
||||||
|
redisAsyncContext *context;
|
||||||
|
aeEventLoop *loop;
|
||||||
|
int fd;
|
||||||
|
int reading, writing;
|
||||||
|
} redisAeEvents;
|
||||||
|
|
||||||
|
void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
|
((void)el); ((void)fd); ((void)mask);
|
||||||
|
|
||||||
|
redisAeEvents *e = (redisAeEvents*)privdata;
|
||||||
|
redisAsyncHandleRead(e->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||||
|
((void)el); ((void)fd); ((void)mask);
|
||||||
|
|
||||||
|
redisAeEvents *e = (redisAeEvents*)privdata;
|
||||||
|
redisAsyncHandleWrite(e->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void redisAeAddRead(void *privdata) {
|
||||||
|
redisAeEvents *e = (redisAeEvents*)privdata;
|
||||||
|
aeEventLoop *loop = e->loop;
|
||||||
|
if (!e->reading) {
|
||||||
|
e->reading = 1;
|
||||||
|
aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void redisAeDelRead(void *privdata) {
|
||||||
|
redisAeEvents *e = (redisAeEvents*)privdata;
|
||||||
|
aeEventLoop *loop = e->loop;
|
||||||
|
if (e->reading) {
|
||||||
|
e->reading = 0;
|
||||||
|
aeDeleteFileEvent(loop,e->fd,AE_READABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void redisAeAddWrite(void *privdata) {
|
||||||
|
redisAeEvents *e = (redisAeEvents*)privdata;
|
||||||
|
aeEventLoop *loop = e->loop;
|
||||||
|
if (!e->writing) {
|
||||||
|
e->writing = 1;
|
||||||
|
aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void redisAeDelWrite(void *privdata) {
|
||||||
|
redisAeEvents *e = (redisAeEvents*)privdata;
|
||||||
|
aeEventLoop *loop = e->loop;
|
||||||
|
if (e->writing) {
|
||||||
|
e->writing = 0;
|
||||||
|
aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void redisAeCleanup(void *privdata) {
|
||||||
|
redisAeEvents *e = (redisAeEvents*)privdata;
|
||||||
|
redisAeDelRead(privdata);
|
||||||
|
redisAeDelWrite(privdata);
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
|
||||||
|
redisContext *c = &(ac->c);
|
||||||
|
redisAeEvents *e;
|
||||||
|
|
||||||
|
/* Nothing should be attached when something is already attached */
|
||||||
|
if (ac->data != NULL)
|
||||||
|
return REDIS_ERR;
|
||||||
|
|
||||||
|
/* Create container for context and r/w events */
|
||||||
|
e = (redisAeEvents*)malloc(sizeof(*e));
|
||||||
|
e->context = ac;
|
||||||
|
e->loop = loop;
|
||||||
|
e->fd = c->fd;
|
||||||
|
e->reading = e->writing = 0;
|
||||||
|
|
||||||
|
/* Register functions to start/stop listening for events */
|
||||||
|
ac->evAddRead = redisAeAddRead;
|
||||||
|
ac->evDelRead = redisAeDelRead;
|
||||||
|
ac->evAddWrite = redisAeAddWrite;
|
||||||
|
ac->evDelWrite = redisAeDelWrite;
|
||||||
|
ac->evCleanup = redisAeCleanup;
|
||||||
|
ac->data = e;
|
||||||
|
|
||||||
|
return REDIS_OK;
|
||||||
|
}
|
||||||
|
|
46
example-ae.c
Normal file
46
example-ae.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "hiredis.h"
|
||||||
|
#include "async.h"
|
||||||
|
#include "adapters/ae.h"
|
||||||
|
|
||||||
|
/* Put event loop in the global scope, so it can be explicitly stopped */
|
||||||
|
static aeEventLoop *loop;
|
||||||
|
|
||||||
|
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
|
||||||
|
redisReply *reply = r;
|
||||||
|
if (reply == NULL) return;
|
||||||
|
printf("argv[%s]: %s\n", (char*)privdata, reply->str);
|
||||||
|
|
||||||
|
/* Disconnect after receiving the reply to GET */
|
||||||
|
redisAsyncDisconnect(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disconnectCallback(const redisAsyncContext *c, int status) {
|
||||||
|
if (status != REDIS_OK) {
|
||||||
|
printf("Error: %s\n", c->errstr);
|
||||||
|
}
|
||||||
|
aeStop(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv) {
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
|
||||||
|
if (c->err) {
|
||||||
|
/* Let *c leak for now... */
|
||||||
|
printf("Error: %s\n", c->errstr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop = aeCreateEventLoop();
|
||||||
|
redisAeAttach(loop, c);
|
||||||
|
redisAsyncSetDisconnectCallback(c,disconnectCallback);
|
||||||
|
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
|
||||||
|
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
|
||||||
|
aeMain(loop);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user