redict/deps/hiredict/adapters/glib.h

168 lines
4.1 KiB
C

/*
* Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
*
* SPDX-FileCopyrightText: 2024 Hiredict Contributors
* SPDX-FileCopyrightText: 2024 Salvatore Sanfilippo <antirez at gmail dot com>
*
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-License-Identifier: LGPL-3.0-or-later
*
*/
#ifndef __HIREDICT_GLIB_H__
#define __HIREDICT_GLIB_H__
#include <glib.h>
#include "../hiredict.h"
#include "../async.h"
typedef struct
{
GSource source;
redictAsyncContext *ac;
GPollFD poll_fd;
} RedictSource;
static void
redict_source_add_read (gpointer data)
{
RedictSource *source = (RedictSource *)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
redict_source_del_read (gpointer data)
{
RedictSource *source = (RedictSource *)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
redict_source_add_write (gpointer data)
{
RedictSource *source = (RedictSource *)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
redict_source_del_write (gpointer data)
{
RedictSource *source = (RedictSource *)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
redict_source_cleanup (gpointer data)
{
RedictSource *source = (RedictSource *)data;
g_return_if_fail(source);
redict_source_del_read(source);
redict_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
redict_source_prepare (GSource *source,
gint *timeout_)
{
RedictSource *redict = (RedictSource *)source;
*timeout_ = -1;
return !!(redict->poll_fd.events & redict->poll_fd.revents);
}
static gboolean
redict_source_check (GSource *source)
{
RedictSource *redict = (RedictSource *)source;
return !!(redict->poll_fd.events & redict->poll_fd.revents);
}
static gboolean
redict_source_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data)
{
RedictSource *redict = (RedictSource *)source;
if ((redict->poll_fd.revents & G_IO_OUT)) {
redictAsyncHandleWrite(redict->ac);
redict->poll_fd.revents &= ~G_IO_OUT;
}
if ((redict->poll_fd.revents & G_IO_IN)) {
redictAsyncHandleRead(redict->ac);
redict->poll_fd.revents &= ~G_IO_IN;
}
if (callback) {
return callback(user_data);
}
return TRUE;
}
static void
redict_source_finalize (GSource *source)
{
RedictSource *redict = (RedictSource *)source;
if (redict->poll_fd.fd >= 0) {
g_source_remove_poll(source, &redict->poll_fd);
redict->poll_fd.fd = -1;
}
}
static GSource *
redict_source_new (redictAsyncContext *ac)
{
static GSourceFuncs source_funcs = {
.prepare = redict_source_prepare,
.check = redict_source_check,
.dispatch = redict_source_dispatch,
.finalize = redict_source_finalize,
};
redictContext *c = &ac->c;
RedictSource *source;
g_return_val_if_fail(ac != NULL, NULL);
source = (RedictSource *)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 = redict_source_add_read;
ac->ev.delRead = redict_source_del_read;
ac->ev.addWrite = redict_source_add_write;
ac->ev.delWrite = redict_source_del_write;
ac->ev.cleanup = redict_source_cleanup;
ac->ev.data = source;
return (GSource *)source;
}
#endif /* __HIREDICT_GLIB_H__ */