Add GLib 2.0 adapter
[Cleaned up Makefile and header includes. Didn't change crazy coding style because it's the convention for GLib systems.] Closes #83 Closes #71
This commit is contained in:
parent
e30c96ebde
commit
0c9ff5bb03
7
Makefile
7
Makefile
@ -4,7 +4,7 @@
|
|||||||
# This file is released under the BSD license, see the COPYING file
|
# This file is released under the BSD license, see the COPYING file
|
||||||
|
|
||||||
OBJ=net.o hiredis.o sds.o async.o
|
OBJ=net.o hiredis.o sds.o async.o
|
||||||
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev
|
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
|
||||||
TESTS=hiredis-test
|
TESTS=hiredis-test
|
||||||
LIBNAME=libhiredis
|
LIBNAME=libhiredis
|
||||||
|
|
||||||
@ -79,6 +79,9 @@ hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLI
|
|||||||
hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
|
hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
|
||||||
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME)
|
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME)
|
||||||
|
|
||||||
|
hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME)
|
||||||
|
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) $(shell pkg-config --cflags --libs glib-2.0) -I. $< $(STLIBNAME)
|
||||||
|
|
||||||
ifndef AE_DIR
|
ifndef AE_DIR
|
||||||
hiredis-example-ae:
|
hiredis-example-ae:
|
||||||
@echo "Please specify AE_DIR (e.g. <redis repository>/src)"
|
@echo "Please specify AE_DIR (e.g. <redis repository>/src)"
|
||||||
@ -103,6 +106,8 @@ hiredis-example: examples/example.c $(STLIBNAME)
|
|||||||
examples: $(EXAMPLES)
|
examples: $(EXAMPLES)
|
||||||
|
|
||||||
hiredis-test: test.o $(STLIBNAME)
|
hiredis-test: test.o $(STLIBNAME)
|
||||||
|
|
||||||
|
hiredis-%: %.o $(STLIBNAME)
|
||||||
$(CC) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
|
$(CC) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
|
||||||
|
|
||||||
test: hiredis-test
|
test: hiredis-test
|
||||||
|
153
adapters/glib.h
Normal file
153
adapters/glib.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#ifndef __HIREDIS_GLIB_H__
|
||||||
|
#define __HIREDIS_GLIB_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "../hiredis.h"
|
||||||
|
#include "../async.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GSource source;
|
||||||
|
redisAsyncContext *ac;
|
||||||
|
GPollFD poll_fd;
|
||||||
|
} RedisSource;
|
||||||
|
|
||||||
|
static void
|
||||||
|
redis_source_add_read (gpointer data)
|
||||||
|
{
|
||||||
|
RedisSource *source = data;
|
||||||
|
g_return_if_fail(source);
|
||||||
|
source->poll_fd.events |= G_IO_IN;
|
||||||
|
g_main_context_wakeup(g_source_get_context(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redis_source_del_read (gpointer data)
|
||||||
|
{
|
||||||
|
RedisSource *source = data;
|
||||||
|
g_return_if_fail(source);
|
||||||
|
source->poll_fd.events &= ~G_IO_IN;
|
||||||
|
g_main_context_wakeup(g_source_get_context(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redis_source_add_write (gpointer data)
|
||||||
|
{
|
||||||
|
RedisSource *source = data;
|
||||||
|
g_return_if_fail(source);
|
||||||
|
source->poll_fd.events |= G_IO_OUT;
|
||||||
|
g_main_context_wakeup(g_source_get_context(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redis_source_del_write (gpointer data)
|
||||||
|
{
|
||||||
|
RedisSource *source = data;
|
||||||
|
g_return_if_fail(source);
|
||||||
|
source->poll_fd.events &= ~G_IO_OUT;
|
||||||
|
g_main_context_wakeup(g_source_get_context(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redis_source_cleanup (gpointer data)
|
||||||
|
{
|
||||||
|
RedisSource *source = data;
|
||||||
|
|
||||||
|
g_return_if_fail(source);
|
||||||
|
|
||||||
|
redis_source_del_read(source);
|
||||||
|
redis_source_del_write(source);
|
||||||
|
/*
|
||||||
|
* It is not our responsibility to remove ourself from the
|
||||||
|
* current main loop. However, we will remove the GPollFD.
|
||||||
|
*/
|
||||||
|
if (source->poll_fd.fd >= 0) {
|
||||||
|
g_source_remove_poll(data, &source->poll_fd);
|
||||||
|
source->poll_fd.fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
redis_source_prepare (GSource *source,
|
||||||
|
gint *timeout_)
|
||||||
|
{
|
||||||
|
RedisSource *redis = (RedisSource *)source;
|
||||||
|
*timeout_ = -1;
|
||||||
|
return !!(redis->poll_fd.events & redis->poll_fd.revents);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
redis_source_check (GSource *source)
|
||||||
|
{
|
||||||
|
RedisSource *redis = (RedisSource *)source;
|
||||||
|
return !!(redis->poll_fd.events & redis->poll_fd.revents);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
redis_source_dispatch (GSource *source,
|
||||||
|
GSourceFunc callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
RedisSource *redis = (RedisSource *)source;
|
||||||
|
|
||||||
|
if ((redis->poll_fd.revents & G_IO_OUT)) {
|
||||||
|
redisAsyncHandleWrite(redis->ac);
|
||||||
|
redis->poll_fd.revents &= ~G_IO_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((redis->poll_fd.revents & G_IO_IN)) {
|
||||||
|
redisAsyncHandleRead(redis->ac);
|
||||||
|
redis->poll_fd.revents &= ~G_IO_IN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
return callback(user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redis_source_finalize (GSource *source)
|
||||||
|
{
|
||||||
|
RedisSource *redis = (RedisSource *)source;
|
||||||
|
|
||||||
|
if (redis->poll_fd.fd >= 0) {
|
||||||
|
g_source_remove_poll(source, &redis->poll_fd);
|
||||||
|
redis->poll_fd.fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSource *
|
||||||
|
redis_source_new (redisAsyncContext *ac)
|
||||||
|
{
|
||||||
|
static GSourceFuncs source_funcs = {
|
||||||
|
.prepare = redis_source_prepare,
|
||||||
|
.check = redis_source_check,
|
||||||
|
.dispatch = redis_source_dispatch,
|
||||||
|
.finalize = redis_source_finalize,
|
||||||
|
};
|
||||||
|
redisContext *c = &ac->c;
|
||||||
|
RedisSource *source;
|
||||||
|
|
||||||
|
g_return_val_if_fail(ac != NULL, NULL);
|
||||||
|
|
||||||
|
source = (RedisSource *)g_source_new(&source_funcs, sizeof *source);
|
||||||
|
source->ac = ac;
|
||||||
|
source->poll_fd.fd = c->fd;
|
||||||
|
source->poll_fd.events = 0;
|
||||||
|
source->poll_fd.revents = 0;
|
||||||
|
g_source_add_poll((GSource *)source, &source->poll_fd);
|
||||||
|
|
||||||
|
ac->ev.addRead = redis_source_add_read;
|
||||||
|
ac->ev.delRead = redis_source_del_read;
|
||||||
|
ac->ev.addWrite = redis_source_add_write;
|
||||||
|
ac->ev.delWrite = redis_source_del_write;
|
||||||
|
ac->ev.cleanup = redis_source_cleanup;
|
||||||
|
ac->ev.data = source;
|
||||||
|
|
||||||
|
return (GSource *)source;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __HIREDIS_GLIB_H__ */
|
73
examples/example-glib.c
Normal file
73
examples/example-glib.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <hiredis.h>
|
||||||
|
#include <async.h>
|
||||||
|
#include <adapters/glib.h>
|
||||||
|
|
||||||
|
static GMainLoop *mainloop;
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
|
||||||
|
int status)
|
||||||
|
{
|
||||||
|
if (status != REDIS_OK) {
|
||||||
|
g_printerr("Failed to connect: %s\n", ac->errstr);
|
||||||
|
g_main_loop_quit(mainloop);
|
||||||
|
} else {
|
||||||
|
g_printerr("Connected...\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
|
||||||
|
int status)
|
||||||
|
{
|
||||||
|
if (status != REDIS_OK) {
|
||||||
|
g_error("Failed to disconnect: %s", ac->errstr);
|
||||||
|
} else {
|
||||||
|
g_printerr("Disconnected...\n");
|
||||||
|
g_main_loop_quit(mainloop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
command_cb(redisAsyncContext *ac,
|
||||||
|
gpointer r,
|
||||||
|
gpointer user_data G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
redisReply *reply = r;
|
||||||
|
|
||||||
|
if (reply) {
|
||||||
|
g_print("REPLY: %s\n", reply->str);
|
||||||
|
}
|
||||||
|
|
||||||
|
redisAsyncDisconnect(ac);
|
||||||
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc G_GNUC_UNUSED,
|
||||||
|
gchar *argv[] G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
redisAsyncContext *ac;
|
||||||
|
GMainContext *context = NULL;
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
ac = redisAsyncConnect("127.0.0.1", 6379);
|
||||||
|
if (ac->err) {
|
||||||
|
g_printerr("%s\n", ac->errstr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
source = redis_source_new(ac);
|
||||||
|
mainloop = g_main_loop_new(context, FALSE);
|
||||||
|
g_source_attach(source, context);
|
||||||
|
|
||||||
|
redisAsyncSetConnectCallback(ac, connect_cb);
|
||||||
|
redisAsyncSetDisconnectCallback(ac, disconnect_cb);
|
||||||
|
redisAsyncCommand(ac, command_cb, NULL, "SET key 1234");
|
||||||
|
redisAsyncCommand(ac, command_cb, NULL, "GET key");
|
||||||
|
|
||||||
|
g_main_loop_run(mainloop);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user