On Wed, 2016-01-13 at 11:39 +0000, Frediano Ziglio wrote: > This code will be reused for main loop > > Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> > --- > server/event-loop.c | 185 > ++++++++++++++++++++++++++++++++++++++++ > server/event-loop.h | 34 ++++++++ > server/tests/Makefile.am | 1 + > server/tests/basic_event_loop.c | 166 +++++------------------------------ > 4 files changed, 242 insertions(+), 144 deletions(-) > create mode 100644 server/event-loop.c > create mode 100644 server/event-loop.h > > diff --git a/server/event-loop.c b/server/event-loop.c > new file mode 100644 > index 0000000..978b4d1 > --- /dev/null > +++ b/server/event-loop.c > @@ -0,0 +1,185 @@ > +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > +/* > + Copyright (C) 2009-2015 Red Hat, Inc. > + > + This library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + This library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with this library; if not, see <http://www.gnu.org/licenses/ > >. > +*/ > +#ifdef HAVE_CONFIG_H > +#include <config.h> > +#endif > + > +#include "spice/macros.h" > +#include "common/mem.h" > +#include "event-loop.h" > + > +#ifndef CORE_CHANNEL_EVENT > +#define CORE_CHANNEL_EVENT NULL > +#endif > + > +struct SpiceTimer { > + GMainContext *context; > + SpiceTimerFunc func; > + void *opaque; > + GSource *source; > +}; > + > +static SpiceTimer* timer_add(const SpiceCoreInterfaceInternal *iface, > + SpiceTimerFunc func, void *opaque) > +{ > + SpiceTimer *timer = spice_malloc0(sizeof(SpiceTimer)); > + > + timer->context = event_loop_context_from_iface(iface); > + timer->func = func; > + timer->opaque = opaque; > + > + return timer; > +} > + > +static gboolean timer_func(gpointer user_data) > +{ > + SpiceTimer *timer = user_data; > + > + timer->func(timer->opaque); > + /* timer might be free after func(), don't touch */ > + > + return FALSE; > +} > + > +static void timer_cancel(SpiceTimer *timer) > +{ > + if (timer->source) { > + g_source_destroy(timer->source); > + g_source_unref(timer->source); > + timer->source = NULL; > + } > +} > + > +static void timer_start(SpiceTimer *timer, uint32_t ms) > +{ > + timer_cancel(timer); > + > + timer->source = g_timeout_source_new(ms); > + spice_assert(timer->source != NULL); > + > + g_source_set_callback(timer->source, timer_func, timer, NULL); > + > + g_source_attach(timer->source, timer->context); > +} > + > +static void timer_remove(SpiceTimer *timer) > +{ > + timer_cancel(timer); > + spice_assert(timer->source == NULL); > + free(timer); > +} > + > +struct SpiceWatch { > + GMainContext *context; > + void *opaque; > + GSource *source; > + GIOChannel *channel; > + SpiceWatchFunc func; > +}; > + > +static GIOCondition spice_event_to_giocondition(int event_mask) > +{ > + GIOCondition condition = 0; > + > + if (event_mask & SPICE_WATCH_EVENT_READ) > + condition |= G_IO_IN; > + if (event_mask & SPICE_WATCH_EVENT_WRITE) > + condition |= G_IO_OUT; > + > + return condition; > +} > + > +static int giocondition_to_spice_event(GIOCondition condition) > +{ > + int event = 0; > + > + if (condition & G_IO_IN) > + event |= SPICE_WATCH_EVENT_READ; > + if (condition & G_IO_OUT) > + event |= SPICE_WATCH_EVENT_WRITE; > + > + return event; > +} > + > +static gboolean watch_func(GIOChannel *source, GIOCondition condition, > + gpointer data) > +{ > + SpiceWatch *watch = data; > + int fd = g_io_channel_unix_get_fd(source); > + > + watch->func(fd, giocondition_to_spice_event(condition), watch->opaque); > + > + return TRUE; > +} > + > +static void watch_update_mask(SpiceWatch *watch, int event_mask) > +{ > + if (watch->source) { > + g_source_destroy(watch->source); > + g_source_unref(watch->source); > + watch->source = NULL; > + } > + > + if (!event_mask) > + return; > + > + watch->source = g_io_create_watch(watch->channel, > spice_event_to_giocondition(event_mask)); > + g_source_set_callback(watch->source, (GSourceFunc)watch_func, watch, > NULL); > + g_source_attach(watch->source, watch->context); > +} > + > +static SpiceWatch *watch_add(const SpiceCoreInterfaceInternal *iface, > + int fd, int event_mask, SpiceWatchFunc func, > void *opaque) > +{ > + SpiceWatch *watch; > + > + spice_return_val_if_fail(fd != -1, NULL); > + spice_return_val_if_fail(func != NULL, NULL); > + > + watch = spice_malloc0(sizeof(SpiceWatch)); > + watch->context = event_loop_context_from_iface(iface); > + watch->channel = g_io_channel_unix_new(fd); > + watch->func = func; > + watch->opaque = opaque; > + > + watch_update_mask(watch, event_mask); > + > + return watch; > +} > + > +static void watch_remove(SpiceWatch *watch) > +{ > + watch_update_mask(watch, 0); > + spice_assert(watch->source == NULL); > + > + g_io_channel_unref(watch->channel); > + free(watch); > +} > + > +SpiceCoreInterfaceInternal event_loop_core = { > + .timer_add = timer_add, > + .timer_start = timer_start, > + .timer_cancel = timer_cancel, > + .timer_remove = timer_remove, > + > + .watch_add = watch_add, > + .watch_update_mask = watch_update_mask, > + .watch_remove = watch_remove, > + > + .channel_event = event_loop_channel_event > +}; > diff --git a/server/event-loop.h b/server/event-loop.h > new file mode 100644 > index 0000000..2a0a56a > --- /dev/null > +++ b/server/event-loop.h > @@ -0,0 +1,34 @@ > +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > +/* > + Copyright (C) 2009-2015 Red Hat, Inc. > + > + This library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + This library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with this library; if not, see <http://www.gnu.org/licenses/ > >. > +*/ > + > +#ifndef EVENT_LOOP_H_ > +#define EVENT_LOOP_H_ > + > +#include "red-common.h" > + > +#include <glib.h> > + > +extern SpiceCoreInterfaceInternal event_loop_core; > + > +/* Missing functions to be defined externally */ > + > +GMainContext *event_loop_context_from_iface(const SpiceCoreInterfaceInternal > *opaque); > + > +void event_loop_channel_event(int event, SpiceChannelEventInfo *info); > + > +#endif /* EVENT_LOOP_H_ */ > diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am > index 981c570..4532d78 100644 > --- a/server/tests/Makefile.am > +++ b/server/tests/Makefile.am > @@ -28,6 +28,7 @@ LDADD = > \ > COMMON_BASE = \ > basic_event_loop.c \ > basic_event_loop.h \ > + ../event-loop.c \ > $(NULL) > > noinst_PROGRAMS = \ > diff --git a/server/tests/basic_event_loop.c b/server/tests/basic_event_loop.c > index 15fba65..0eac194 100644 > --- a/server/tests/basic_event_loop.c > +++ b/server/tests/basic_event_loop.c > @@ -25,6 +25,7 @@ > #include "spice/macros.h" > #include "common/ring.h" > #include "common/mem.h" > +#include "../event-loop.h" > #include "basic_event_loop.h" > > int debug = 0; > @@ -42,145 +43,12 @@ GMainContext *basic_event_loop_get_context(void) > return main_context; > } > > -struct SpiceTimer { > - SpiceTimerFunc func; > - void *opaque; > - GSource *source; > -}; > - > -static SpiceTimer* timer_add(SpiceTimerFunc func, void *opaque) > -{ > - SpiceTimer *timer = spice_malloc0(sizeof(SpiceTimer)); > - > - timer->func = func; > - timer->opaque = opaque; > - > - return timer; > -} > - > -static gboolean timer_func(gpointer user_data) > -{ > - SpiceTimer *timer = user_data; > - > - timer->func(timer->opaque); > - /* timer might be free after func(), don't touch */ > - > - return FALSE; > -} > - > -static void timer_cancel(SpiceTimer *timer) > -{ > - if (timer->source) { > - g_source_destroy(timer->source); > - g_source_unref(timer->source); > - timer->source = NULL; > - } > -} > - > -static void timer_start(SpiceTimer *timer, uint32_t ms) > +GMainContext *event_loop_context_from_iface(const SpiceCoreInterfaceInternal > *iface) > { > - timer_cancel(timer); > - > - timer->source = g_timeout_source_new(ms); > - spice_assert(timer->source != NULL); > - > - g_source_set_callback(timer->source, timer_func, timer, NULL); > - > - g_source_attach(timer->source, main_context); > -} > - > -static void timer_remove(SpiceTimer *timer) > -{ > - timer_cancel(timer); > - spice_assert(timer->source == NULL); > - free(timer); > -} > - > -struct SpiceWatch { > - void *opaque; > - GSource *source; > - GIOChannel *channel; > - SpiceWatchFunc func; > -}; > - > -static GIOCondition spice_event_to_giocondition(int event_mask) > -{ > - GIOCondition condition = 0; > - > - if (event_mask & SPICE_WATCH_EVENT_READ) > - condition |= G_IO_IN; > - if (event_mask & SPICE_WATCH_EVENT_WRITE) > - condition |= G_IO_OUT; > - > - return condition; > -} > - > -static int giocondition_to_spice_event(GIOCondition condition) > -{ > - int event = 0; > - > - if (condition & G_IO_IN) > - event |= SPICE_WATCH_EVENT_READ; > - if (condition & G_IO_OUT) > - event |= SPICE_WATCH_EVENT_WRITE; > - > - return event; > -} > - > -static gboolean watch_func(GIOChannel *source, GIOCondition condition, > - gpointer data) > -{ > - SpiceWatch *watch = data; > - int fd = g_io_channel_unix_get_fd(source); > - > - watch->func(fd, giocondition_to_spice_event(condition), watch->opaque); > - > - return TRUE; > -} > - > -static void watch_update_mask(SpiceWatch *watch, int event_mask) > -{ > - if (watch->source) { > - g_source_destroy(watch->source); > - g_source_unref(watch->source); > - watch->source = NULL; > - } > - > - if (!event_mask) > - return; > - > - watch->source = g_io_create_watch(watch->channel, > spice_event_to_giocondition(event_mask)); > - g_source_set_callback(watch->source, (GSourceFunc)watch_func, watch, > NULL); > - g_source_attach(watch->source, main_context); > -} > - > -static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, > void *opaque) > -{ > - SpiceWatch *watch; > - > - spice_return_val_if_fail(fd != -1, NULL); > - spice_return_val_if_fail(func != NULL, NULL); > - > - watch = spice_malloc0(sizeof(SpiceWatch)); > - watch->channel = g_io_channel_unix_new(fd); > - watch->func = func; > - watch->opaque = opaque; > - > - watch_update_mask(watch, event_mask); > - > - return watch; > -} > - > -static void watch_remove(SpiceWatch *watch) > -{ > - watch_update_mask(watch, 0); > - spice_assert(watch->source == NULL); > - > - g_io_channel_unref(watch->channel); > - free(watch); > + return main_context; > } > > -static void channel_event(int event, SpiceChannelEventInfo *info) > +void event_loop_channel_event(int event, SpiceChannelEventInfo *info) > { > DPRINTF(0, "channel event con, type, id, event: %d, %d, %d, %d", > info->connection_id, info->type, info->id, event); > @@ -204,19 +72,24 @@ static void ignore_sigpipe(void) > sigaction(SIGPIPE, &act, NULL); > } > > +static SpiceTimer* base_timer_add(SpiceTimerFunc func, void *opaque) > +{ > + return event_loop_core.timer_add(NULL, func, opaque); > +} > + > +static SpiceWatch *base_watch_add(int fd, int event_mask, SpiceWatchFunc > func, void *opaque) > +{ > + return event_loop_core.watch_add(NULL, fd, event_mask, func, opaque); > +} > + > static SpiceCoreInterface core = { > .base = { > .major_version = SPICE_INTERFACE_CORE_MAJOR, > .minor_version = SPICE_INTERFACE_CORE_MINOR, > }, > - .timer_add = timer_add, > - .timer_start = timer_start, > - .timer_cancel = timer_cancel, > - .timer_remove = timer_remove, > - .watch_add = watch_add, > - .watch_update_mask = watch_update_mask, > - .watch_remove = watch_remove, > - .channel_event = channel_event, > + .timer_add = base_timer_add, > + .watch_add = base_watch_add, > + .channel_event = event_loop_channel_event, > }; > > SpiceCoreInterface *basic_event_loop_init(void) > @@ -224,5 +97,10 @@ SpiceCoreInterface *basic_event_loop_init(void) > ignore_sigpipe(); > spice_assert(main_context == NULL); > main_context = g_main_context_new(); > + core.timer_start = event_loop_core.timer_start; > + core.timer_cancel = event_loop_core.timer_cancel; > + core.timer_remove = event_loop_core.timer_remove; > + core.watch_update_mask = event_loop_core.watch_update_mask; > + core.watch_remove = event_loop_core.watch_remove; I'm curious, why were these initializations moved here? > return &core; > } _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel