|
- #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 = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events |= G_IO_IN;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
- }
-
- static void
- redis_source_del_read (gpointer data)
- {
- RedisSource *source = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events &= ~G_IO_IN;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
- }
-
- static void
- redis_source_add_write (gpointer data)
- {
- RedisSource *source = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events |= G_IO_OUT;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
- }
-
- static void
- redis_source_del_write (gpointer data)
- {
- RedisSource *source = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events &= ~G_IO_OUT;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
- }
-
- static void
- redis_source_cleanup (gpointer data)
- {
- RedisSource *source = (RedisSource *)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((GSource *)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);
- if (source == NULL)
- return NULL;
-
- 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__ */
|