ping > > ping > > > > > Avoid having to destroy and create a new GSource every time > > we change event mask. > > Interfaces required for this patch are available since GLib 2.36. > > on Windows GPollFD::fd can be an HANDLE but not a socket. > > > > Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> > > --- > > server/event-loop.c | 97 +++++++++++++++++++++++++++++++++++++++------ > > 1 file changed, 85 insertions(+), 12 deletions(-) > > > > diff --git a/server/event-loop.c b/server/event-loop.c > > index 80af2954f..33db4ffb0 100644 > > --- a/server/event-loop.c > > +++ b/server/event-loop.c > > @@ -85,14 +85,6 @@ static void timer_remove(const > > SpiceCoreInterfaceInternal > > *iface, > > g_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; > > @@ -117,6 +109,15 @@ static int giocondition_to_spice_event(GIOCondition > > condition) > > return event; > > } > > > > +#ifdef _WIN32 > > +struct SpiceWatch { > > + GMainContext *context; > > + void *opaque; > > + GSource *source; > > + GIOChannel *channel; > > + SpiceWatchFunc func; > > +}; > > + > > static gboolean watch_func(GIOChannel *source, GIOCondition condition, > > gpointer data) > > { > > @@ -161,11 +162,7 @@ static SpiceWatch *watch_add(const > > SpiceCoreInterfaceInternal *iface, > > > > watch = g_new0(SpiceWatch, 1); > > watch->context = iface->main_context; > > -#ifndef _WIN32 > > - watch->channel = g_io_channel_unix_new(fd); > > -#else > > watch->channel = g_io_channel_win32_new_socket(fd); > > -#endif > > watch->func = func; > > watch->opaque = opaque; > > > > @@ -184,6 +181,82 @@ static void watch_remove(const > > SpiceCoreInterfaceInternal *iface, > > g_free(watch); > > } > > > > +#else > > + > > +struct SpiceWatch { > > + GSource source; > > + GPollFD pollfd; > > +}; > > + > > +static gboolean > > +spice_watch_check(GSource *source) > > +{ > > + SpiceWatch *watch = SPICE_CONTAINEROF(source, SpiceWatch, source); > > + > > + return watch->pollfd.events & watch->pollfd.revents; > > +} > > + > > +static gboolean > > +spice_watch_dispatch(GSource *source, > > + GSourceFunc callback, > > + gpointer user_data) > > +{ > > + SpiceWatch *watch = SPICE_CONTAINEROF(source, SpiceWatch, source); > > + SpiceWatchFunc func = (SpiceWatchFunc)(void*) callback; > > + > > + func(watch->pollfd.fd, > > giocondition_to_spice_event(watch->pollfd.revents), user_data); > > + /* timer might be free after func(), don't touch */ > > + > > + return G_SOURCE_CONTINUE; > > +} > > + > > +static GSourceFuncs spice_watch_funcs = { > > + .check = spice_watch_check, > > + .dispatch = spice_watch_dispatch, > > +}; > > + > > +static void watch_update_mask(const SpiceCoreInterfaceInternal *iface, > > + SpiceWatch *watch, int event_mask) > > +{ > > + GIOCondition old_condition = watch->pollfd.events; > > + GIOCondition new_condition = spice_event_to_giocondition(event_mask); > > + > > + watch->pollfd.events = new_condition; > > + if (old_condition && !new_condition) { > > + g_source_remove_poll(&watch->source, &watch->pollfd); > > + } else if (!old_condition && new_condition) { > > + g_source_add_poll(&watch->source, &watch->pollfd); > > + } > > +} > > + > > +static SpiceWatch *watch_add(const SpiceCoreInterfaceInternal *iface, > > + int fd, int event_mask, SpiceWatchFunc func, > > void *opaque) > > +{ > > + SpiceWatch *watch = (SpiceWatch *) g_source_new(&spice_watch_funcs, > > sizeof(SpiceWatch)); > > + > > + spice_return_val_if_fail(fd != -1, NULL); > > + spice_return_val_if_fail(func != NULL, NULL); > > + > > + watch->pollfd.fd = fd; > > + watch->pollfd.events = 0; > > + > > + g_source_set_callback(&watch->source, > > (GSourceFunc)(void*)(SpiceWatchFunc) func, opaque, NULL); > > + > > + g_source_attach(&watch->source, iface->main_context); > > + > > + watch_update_mask(iface, watch, event_mask); > > + > > + return watch; > > +} > > + > > +static void watch_remove(const SpiceCoreInterfaceInternal *iface, > > + SpiceWatch *watch) > > +{ > > + g_source_destroy(&watch->source); > > + g_source_unref(&watch->source); > > +} > > +#endif > > + > > const SpiceCoreInterfaceInternal event_loop_core = { > > .timer_add = timer_add, > > .timer_start = timer_start, _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel