diff options
| author | Christian Hergert <chris@dronelabs.com> | 2012-02-08 03:07:48 -0800 | 
|---|---|---|
| committer | Matt Stancliff <matt@genges.com> | 2015-01-05 16:39:30 -0500 | 
| commit | 0c9ff5bb030fd07706c39b3d4f28cef618dd8794 (patch) | |
| tree | 1e4d4e48292511bffa7ee546e071044f6f852a72 /adapters | |
| parent | e30c96ebdec4e8612f4102f9cd99d36488c66e5c (diff) | |
| download | hiredict-0c9ff5bb030fd07706c39b3d4f28cef618dd8794.tar.xz | |
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
Diffstat (limited to 'adapters')
| -rw-r--r-- | adapters/glib.h | 153 | 
1 files changed, 153 insertions, 0 deletions
diff --git a/adapters/glib.h b/adapters/glib.h new file mode 100644 index 0000000..e13eee7 --- /dev/null +++ b/adapters/glib.h @@ -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__ */  | 
