[virt-tools-list] [virt-viewer][PATCH] events: "backport" a few patches from libvirt-glib-events to virt-viewer -- missing patch

2015-07-17 Thread Fabiano Fidêncio
This patch should part of the previous series that I sent [0].

[0]: https://www.redhat.com/archives/virt-tools-list/2015-July/msg00063.html

Fabiano Fidêncio (1):
  events: Don't leak GIOChannel when destroying IO handle

 src/virt-viewer-events.c | 4 
 1 file changed, 4 insertions(+)

-- 
2.4.4

___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH 4/6] events: protect "handles" and "timeouts" agins concurrent access

2015-07-17 Thread Victor Toso
Typo in the short commit message: against

On Fri, Jul 17, 2015 at 04:01:21PM +0200, Fabiano Fidêncio wrote:
> Timeout and Handle operations are done from an idle callback. However,
> we cannot assume that all libvirt event calls (the callbacks passed to
> virEventRegisterImpl) will be done from the mainloop thread. It's thus
> possible that a libvirt event call will run a thread while one of the
> callbacks runs.
> Given that "handles" and "timeouts" arrays are shared among all threads,
> we need to make sure we hold the "eventlock" mutex before modifying
> them.
> 
> Based on
> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=924178f6b35735458b37d30303fe7bc753dde0b1
> 
> Related to: rhbz#1243228
> ---
>  src/virt-viewer-events.c | 109 
> +++
>  1 file changed, 82 insertions(+), 27 deletions(-)
> 
> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
> index b92506c..ef2c317 100644
> --- a/src/virt-viewer-events.c
> +++ b/src/virt-viewer-events.c
> @@ -33,6 +33,9 @@
>  #include 
>  
>  #include "virt-viewer-events.h"
> +#include "virt-glib-compat.h"
> +
> +GMutex *eventlock = NULL;
>  
>  struct virt_viewer_events_handle
>  {
> @@ -84,6 +87,9 @@ int virt_viewer_events_add_handle(int fd,
>  {
>  struct virt_viewer_events_handle *data;
>  GIOCondition cond = 0;
> +int ret;
> +
> +g_mutex_lock(eventlock);
>  
>  data = g_new0(struct virt_viewer_events_handle, 1);
>  
> @@ -114,7 +120,11 @@ int virt_viewer_events_add_handle(int fd,
>  
>  g_ptr_array_add(handles, data);
>  
> -return data->watch;
> +ret = data->watch;
> +
> +g_mutex_unlock(eventlock);
> +
> +return ret;
>  }
>  
>  static struct virt_viewer_events_handle *
> @@ -144,19 +154,22 @@ static void
>  virt_viewer_events_update_handle(int watch,
>   int events)
>  {
> -struct virt_viewer_events_handle *data = 
> virt_viewer_events_find_handle(watch);
> +struct virt_viewer_events_handle *data;
> +
> +g_mutex_lock(eventlock);
>  
> -if (!data) {
> +data = virt_viewer_events_find_handle(watch);
> +if (data == NULL) {
>  g_debug("Update for missing handle watch %d", watch);
> -return;
> +goto cleanup;
>  }
>  
> -if (events) {
> +if (events != 0) {
>  GIOCondition cond = 0;
>  if (events == data->events)
> -return;
> +goto cleanup;
>  
> -if (data->source)
> +if (data->source != 0)
>  g_source_remove(data->source);
>  
>  cond |= G_IO_HUP;
> @@ -170,13 +183,16 @@ virt_viewer_events_update_handle(int watch,
>data);
>  data->events = events;
>  } else {
> -if (!data->source)
> -return;
> +if (data->source == 0)
> +goto cleanup;
>  
>  g_source_remove(data->source);
>  data->source = 0;
>  data->events = 0;
>  }
> +
> +cleanup:
> +g_mutex_unlock(eventlock);
>  }
>  
>  
> @@ -191,7 +207,10 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
>  if (data->ff)
>  (data->ff)(data->opaque);
>  
> +g_mutex_lock(eventlock);
>  g_ptr_array_remove_fast(handles, data);
> +g_mutex_unlock(eventlock);
> +
>  return FALSE;
>  }
>  
> @@ -199,16 +218,20 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
>  static int
>  virt_viewer_events_remove_handle(int watch)
>  {
> -struct virt_viewer_events_handle *data = 
> virt_viewer_events_find_handle(watch);
> +struct virt_viewer_events_handle *data;
> +int ret = -1;
>  
> -if (!data) {
> +g_mutex_lock(eventlock);
> +
> +data = virt_viewer_events_find_handle(watch);
> +if (data == NULL) {
>  g_debug("Remove of missing watch %d", watch);
> -return -1;
> +goto cleanup;
>  }
>  
>  g_debug("Remove handle %d %d", watch, data->fd);
>  
> -if (data->source) {
> +if (data->source != 0) {
>  g_source_remove(data->source);
>  data->source = 0;
>  data->events = 0;
> @@ -220,7 +243,12 @@ virt_viewer_events_remove_handle(int watch)
>   */
>  data->removed = TRUE;
>  g_idle_add(virt_viewer_events_cleanup_handle, data);
> -return 0;
> +ret = 0;
> +
> +cleanup:
> +g_mutex_unlock(eventlock);
> +
> +return ret;
>  }
>  
>  struct virt_viewer_events_timeout
> @@ -255,6 +283,9 @@ virt_viewer_events_add_timeout(int interval,
> virFreeCallback ff)
>  {
>  struct virt_viewer_events_timeout *data;
> +int ret;
> +
> +g_mutex_lock(eventlock);
>  
>  data = g_new0(struct virt_viewer_events_timeout, 1);
>  
> @@ -272,7 +303,11 @@ virt_viewer_events_add_timeout(int interval,
>  
>  g_debug("Add timeout %p %d %p %p %d", data, interval, cb, opaque, 
> data->timer);
>  
> -return data->timer;
> +ret = data->timer;
> +
> +g_mutex_unlock(eventlock);
> +

Re: [virt-tools-list] [virt-viewer][PATCH 0/6] events: "backport" a few patches from libvirt-glib-events to virt-viewer

2015-07-17 Thread Christophe Fergeau
An alternative to this series is to revert
https://git.fedorahosted.org/cgit/virt-viewer.git/commit/?id=296f91c
(which would mean a new dependency not available in EL6). libvirt-glib
mainloop implementation has matured a lot in the mean time as shown by
this series ;)

Christophe

On Fri, Jul 17, 2015 at 04:01:17PM +0200, Fabiano Fidêncio wrote:
> In order to fix rhbz#1243228, I am "backporting" a few fixes from
> libvirt-glib/libvirt-glib-events.c to virt-viewer, as the events
> file used for both seems to be pretty much the same (with the same
> issues as well, sometimes fixed in one, sometimes fixed in the other).
> 
> All patches have a link for the relevant commit in the libvirt-glib.
> 
> These patches were already tested by the reporter of rhbz#1243228.
> 
> Fabiano Fidêncio (6):
>   events: Register event using GOnce to avoid multiple initializations
>   events: remove timeout and handle from arrays
>   glib-compat: Add g_mutex_new()
>   events: protect "handles" and "timeouts" agins concurrent access
>   events: Don't create glib IO watch for disabled handles
>   events: Allow zero timeouts for timer
> 
>  src/virt-glib-compat.h   |   4 +
>  src/virt-viewer-events.c | 224 
> +--
>  2 files changed, 163 insertions(+), 65 deletions(-)
> 
> -- 
> 2.4.4
> 
> ___
> virt-tools-list mailing list
> virt-tools-list@redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list


pgpvRA1yIXGnA.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH 6/6] events: Allow zero timeouts for timer

2015-07-17 Thread Christophe Fergeau
ACK, though this one comes much sooner in libvirt-glib history.

Christophe

On Fri, Jul 17, 2015 at 04:01:23PM +0200, Fabiano Fidêncio wrote:
> In libvirt, it's perfectly possible and widely used to have disabled
> timers (timeout=-1) and fire them up 'randomly' with timeout=0.
> However, with current mapping into glib mainloop it's not possible
> and causing troubles.
> 
> Based on
> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=a40a1732e0d53fcc44b8d348cec97152dafd2b88
> 
> Related to: rhbz#1243228
> ---
>  src/virt-viewer-events.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
> index c6442f6..d36dd3a 100644
> --- a/src/virt-viewer-events.c
> +++ b/src/virt-viewer-events.c
> @@ -355,7 +355,7 @@ virt_viewer_events_update_timeout(int timer,
>  
>  if (interval >= 0) {
>  if (data->source != 0)
> -goto cleanup;
> +g_source_remove(data->source);
>  
>  data->interval = interval;
>  data->source = g_timeout_add(data->interval,
> -- 
> 2.4.4
> 
> ___
> virt-tools-list mailing list
> virt-tools-list@redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list


pgpNTTRZYlxHL.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH 2/6] events: remove timeout and handle from arrays

2015-07-17 Thread Fabiano Fidêncio
On Fri, Jul 17, 2015 at 6:15 PM, Christophe Fergeau  wrote:
> Hey,
>
> On Fri, Jul 17, 2015 at 04:01:19PM +0200, Fabiano Fidêncio wrote:
>> Based on
>> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=cff5f1c46f4b9661e112b85159fb58ae473a9a89
>
> I'd tend to c&p the initial log too

Not sure if the initial log would make sense here. But I can c&p it, no problem.

>
>>
>> Related to: rhbz#1243228
>> ---
>>  src/virt-viewer-events.c | 97 
>> +++-
>>  1 file changed, 63 insertions(+), 34 deletions(-)
>>
>> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
>> index 6154353..b92506c 100644
>> --- a/src/virt-viewer-events.c
>> +++ b/src/virt-viewer-events.c
>> @@ -39,7 +39,7 @@ struct virt_viewer_events_handle
>>  int watch;
>>  int fd;
>>  int events;
>> -int enabled;
>> +int removed;
>
> This (and other parts of this commit) are
> https://libvirt.org/git/?p=libvirt-glib.git;a=commitdiff;h=3e73e0cee977fb20dd29db3ccfe85b00cc386c43
> they should go in a separate commit

As it was not exactly cherry-picked from the libvirt-glib commits, I
don't see a good reason for not having all the fixes squashed when
they make sense to be squashed.


>
>>  GIOChannel *channel;
>>  guint source;
>>  virEventHandleCallback cb;
>> @@ -48,8 +48,7 @@ struct virt_viewer_events_handle
>>  };
>>
>>  static int nextwatch = 1;
>> -static unsigned int nhandles = 0;
>> -static struct virt_viewer_events_handle **handles = NULL;
>> +GPtrArray *handles;
>
> static GPtrArray
>
>>
>>  static gboolean
>>  virt_viewer_events_dispatch_handle(GIOChannel *source G_GNUC_UNUSED,
>> @@ -86,9 +85,7 @@ int virt_viewer_events_add_handle(int fd,
>>  struct virt_viewer_events_handle *data;
>>  GIOCondition cond = 0;
>>
>> -handles = g_realloc(handles, sizeof(*handles)*(nhandles+1));
>> -data = g_malloc(sizeof(*data));
>> -memset(data, 0, sizeof(*data));
>> +data = g_new0(struct virt_viewer_events_handle, 1);
>>
>>  if (events & VIR_EVENT_HANDLE_READABLE)
>>  cond |= G_IO_IN;
>> @@ -115,7 +112,7 @@ int virt_viewer_events_add_handle(int fd,
>>virt_viewer_events_dispatch_handle,
>>data);
>>
>> -handles[nhandles++] = data;
>> +g_ptr_array_add(handles, data);
>>
>>  return data->watch;
>>  }
>> @@ -123,10 +120,22 @@ int virt_viewer_events_add_handle(int fd,
>>  static struct virt_viewer_events_handle *
>>  virt_viewer_events_find_handle(int watch)
>
> any reason for not keeping the guint *idx arg added in the source
> commit?

Yeah, as you mentioned, I squashed
https://libvirt.org/git/?p=libvirt-glib.git;a=commitdiff;h=1fb34633ef3b318ea678b775d5e47debc98d2184

>
>>  {
>> -unsigned int i;
>> -for (i = 0 ; i < nhandles ; i++)
>> -if (handles[i]->watch == watch)
>> -return handles[i];
>> +guint i;
>> +
>> +g_return_val_if_fail(handles != NULL, NULL);
>> +
>> +for (i = 0; i < handles->len; i++) {
>> +struct virt_viewer_events_handle *h = g_ptr_array_index(handles, i);
>> +
>> +if (h == NULL) {
>> +g_warn_if_reached();
>> +continue;
>> +}
>> +
>> +if ((h->watch == watch) && !h->removed) {
>> +return h;
>> +}
>> +}
>>
>>  return NULL;
>>  }
>> @@ -182,7 +191,7 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
>>  if (data->ff)
>>  (data->ff)(data->opaque);
>>
>> -free(data);
>> +g_ptr_array_remove_fast(handles, data);
>>  return FALSE;
>>  }
>>
>> @@ -199,13 +208,17 @@ virt_viewer_events_remove_handle(int watch)
>>
>>  g_debug("Remove handle %d %d", watch, data->fd);
>>
>> -if (!data->source)
>> -return -1;
>> -
>> -g_source_remove(data->source);
>> -data->source = 0;
>> -data->events = 0;
>> +if (data->source) {
>> +g_source_remove(data->source);
>> +data->source = 0;
>> +data->events = 0;
>> +}
>>
>> +/* since the actual watch deletion is done asynchronously, a 
>> handle_update call may
>> + * reschedule the watch befure it's fully deleted, that's why we need 
>> to mar it as
>
> 'before' 'mark'
>
>
>> + * 'removed' to prevent reuse
>> + */
>> +data->removed = TRUE;
>>  g_idle_add(virt_viewer_events_cleanup_handle, data);
>>  return 0;
>>  }
>> @@ -214,6 +227,7 @@ struct virt_viewer_events_timeout
>>  {
>>  int timer;
>>  int interval;
>> +int removed;
>>  guint source;
>>  virEventTimeoutCallback cb;
>>  void *opaque;
>> @@ -222,8 +236,7 @@ struct virt_viewer_events_timeout
>>
>>
>>  static int nexttimer = 1;
>> -static unsigned int ntimeouts = 0;
>> -static struct virt_viewer_events_timeout **timeouts = NULL;
>> +GPtrArray *timeouts;
>
> static
>
>>
>>  static gboolean
>>  virt_viewer_events_dispatch_timeout(void *opaque)
>> @@ -243,9 +256,7 @@ virt_viewer_events_add_timeout(int interval,

Re: [virt-tools-list] [virt-viewer][PATCH 5/6] events: Don't create glib IO watch for disabled handles

2015-07-17 Thread Christophe Fergeau
ACK.

On Fri, Jul 17, 2015 at 04:01:22PM +0200, Fabiano Fidêncio wrote:
> It's possible to create a handle to watch for file events which do not
> watch for any file event. Such a handle can be enabled later with
> gvir_event_handle_update() by setting some conditions to watch for.
> 
> When a handle is disabled after it has been created,
> gvir_event_handle_update() makes sure it removes the corresponding
> gvir_event_handle::source IO watch if any was set.
> gvir_event_handle_add() will always create a gvir_event_handle::source
> IO watch even if the handle is not watching for any events.
> 
> This commit makes consistent by only creating a watch with g_io_add_watch()
> when the caller asked to watch for some events.
> 
> Based on
> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=d71c143936a35cd6c3f23ae0cbf7f3215d944051
> 
> Related to: rhbz#1243228
> ---
>  src/virt-viewer-events.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
> index ef2c317..c6442f6 100644
> --- a/src/virt-viewer-events.c
> +++ b/src/virt-viewer-events.c
> @@ -113,10 +113,12 @@ int virt_viewer_events_add_handle(int fd,
>  
>  g_debug("Add handle %d %d %p", data->fd, events, data->opaque);
>  
> -data->source = g_io_add_watch(data->channel,
> -  cond,
> -  virt_viewer_events_dispatch_handle,
> -  data);
> +if (events != 0) {
> +data->source = g_io_add_watch(data->channel,
> +  cond,
> +  virt_viewer_events_dispatch_handle,
> +  data);
> +}
>  
>  g_ptr_array_add(handles, data);
>  
> -- 
> 2.4.4
> 
> ___
> virt-tools-list mailing list
> virt-tools-list@redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list


pgpxPOKJkqD1t.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH] events: Don't leak GIOChannel when destroying IO handle

2015-07-17 Thread Christophe Fergeau
ACK.

On Fri, Jul 17, 2015 at 06:33:51PM +0200, Fabiano Fidêncio wrote:
> virt_viewer_events_add_handle() creates a GIOChannel in order to watch
> the fd it was given for changes.
> virt_viewer_events_remove_handle() is freeing all the resources
> allocated by virt_viewer_events_add_handle() expect for this GIOChannel.
> This commit adds the needed g_io_channel_unref() call to
> virt_viewer_events_remove_handle().
> 
> Based on
> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=8e95b8d25a3eee6316aff2f83b0c449aaf10984a
> 
> Related to: rhbz#1243228
> ---
>  src/virt-viewer-events.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
> index d36dd3a..6cdc56a 100644
> --- a/src/virt-viewer-events.c
> +++ b/src/virt-viewer-events.c
> @@ -239,6 +239,10 @@ virt_viewer_events_remove_handle(int watch)
>  data->events = 0;
>  }
>  
> +g_warn_if_fail(data->channel != NULL);
> +g_io_channel_unref(data->channel);
> +data->channel = NULL;
> +
>  /* since the actual watch deletion is done asynchronously, a 
> handle_update call may
>   * reschedule the watch befure it's fully deleted, that's why we need to 
> mar it as
>   * 'removed' to prevent reuse
> -- 
> 2.4.4
> 
> ___
> virt-tools-list mailing list
> virt-tools-list@redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list


pgpKOmJzsVTX_.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH 4/6] events: protect "handles" and "timeouts" agins concurrent access

2015-07-17 Thread Christophe Fergeau
On Fri, Jul 17, 2015 at 04:01:21PM +0200, Fabiano Fidêncio wrote:
> Timeout and Handle operations are done from an idle callback. However,
> we cannot assume that all libvirt event calls (the callbacks passed to
> virEventRegisterImpl) will be done from the mainloop thread. It's thus
> possible that a libvirt event call will run a thread while one of the
> callbacks runs.
> Given that "handles" and "timeouts" arrays are shared among all threads,
> we need to make sure we hold the "eventlock" mutex before modifying
> them.
> 
> Based on
> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=924178f6b35735458b37d30303fe7bc753dde0b1

This really is
https://libvirt.org/git/?p=libvirt-glib.git;a=commitdiff;h=f1fe67da2dac6a249f796535b8dbd155d5741ad7
with
http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=924178f6b35735458b37d30303fe7bc753dde0b1
and
https://libvirt.org/git/?p=libvirt-glib.git;a=commitdiff;h=dd17c3cc587c73a8c915238f9d9a3e200e89c93f
squashed in.

> 
> Related to: rhbz#1243228
> ---
>  src/virt-viewer-events.c | 109 
> +++
>  1 file changed, 82 insertions(+), 27 deletions(-)
> 
> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
> index b92506c..ef2c317 100644
> --- a/src/virt-viewer-events.c
> +++ b/src/virt-viewer-events.c
> @@ -33,6 +33,9 @@
>  #include 
>  
>  #include "virt-viewer-events.h"
> +#include "virt-glib-compat.h"
> +
> +GMutex *eventlock = NULL;

static GMutex *eventlock

>  
>  struct virt_viewer_events_handle
>  {
> @@ -84,6 +87,9 @@ int virt_viewer_events_add_handle(int fd,
>  {
>  struct virt_viewer_events_handle *data;
>  GIOCondition cond = 0;
> +int ret;
> +
> +g_mutex_lock(eventlock);
>  
>  data = g_new0(struct virt_viewer_events_handle, 1);
>  
> @@ -114,7 +120,11 @@ int virt_viewer_events_add_handle(int fd,
>  
>  g_ptr_array_add(handles, data);
>  
> -return data->watch;
> +ret = data->watch;
> +
> +g_mutex_unlock(eventlock);
> +
> +return ret;
>  }
>  
>  static struct virt_viewer_events_handle *
> @@ -144,19 +154,22 @@ static void
>  virt_viewer_events_update_handle(int watch,
>   int events)
>  {
> -struct virt_viewer_events_handle *data = 
> virt_viewer_events_find_handle(watch);
> +struct virt_viewer_events_handle *data;
> +
> +g_mutex_lock(eventlock);
>  
> -if (!data) {
> +data = virt_viewer_events_find_handle(watch);
> +if (data == NULL) {

Please don't change if (!data) to your preferred style, this causes
unneeded diff output, and unneeded divergence from the libvirt-glib code

>  g_debug("Update for missing handle watch %d", watch);
> -return;
> +goto cleanup;
>  }
>  
> -if (events) {
> +if (events != 0) {

ditto

>  GIOCondition cond = 0;
>  if (events == data->events)
> -return;
> +goto cleanup;
>  
> -if (data->source)
> +if (data->source != 0)

ditto

>  g_source_remove(data->source);
>  
>  cond |= G_IO_HUP;
> @@ -170,13 +183,16 @@ virt_viewer_events_update_handle(int watch,
>data);
>  data->events = events;
>  } else {
> -if (!data->source)
> -return;
> +if (data->source == 0)
> +goto cleanup;
>  
>  g_source_remove(data->source);
>  data->source = 0;
>  data->events = 0;
>  }
> +
> +cleanup:
> +g_mutex_unlock(eventlock);
>  }
>  
>  
> @@ -191,7 +207,10 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
>  if (data->ff)
>  (data->ff)(data->opaque);
>  
> +g_mutex_lock(eventlock);
>  g_ptr_array_remove_fast(handles, data);
> +g_mutex_unlock(eventlock);
> +
>  return FALSE;
>  }
>  
> @@ -199,16 +218,20 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
>  static int
>  virt_viewer_events_remove_handle(int watch)
>  {
> -struct virt_viewer_events_handle *data = 
> virt_viewer_events_find_handle(watch);
> +struct virt_viewer_events_handle *data;
> +int ret = -1;
>  
> -if (!data) {
> +g_mutex_lock(eventlock);
> +
> +data = virt_viewer_events_find_handle(watch);
> +if (data == NULL) {
>  g_debug("Remove of missing watch %d", watch);
> -return -1;
> +goto cleanup;
>  }
>  
>  g_debug("Remove handle %d %d", watch, data->fd);
>  
> -if (data->source) {
> +if (data->source != 0) {


Here I believe you squashed in
https://libvirt.org/git/?p=libvirt-glib.git;a=commitdiff;h=79699d73e6e1b7218e3bd8349d176752f86128b9

>  g_source_remove(data->source);
>  data->source = 0;
>  data->events = 0;
> @@ -220,7 +243,12 @@ virt_viewer_events_remove_handle(int watch)
>   */
>  data->removed = TRUE;
>  g_idle_add(virt_viewer_events_cleanup_handle, data);
> -return 0;
> +ret = 0;
> +
> +cleanup:
> +g_mutex_unlock(eventlock);
> +
> +re

[virt-tools-list] [virt-viewer][PATCH] events: Don't leak GIOChannel when destroying IO handle

2015-07-17 Thread Fabiano Fidêncio
virt_viewer_events_add_handle() creates a GIOChannel in order to watch
the fd it was given for changes.
virt_viewer_events_remove_handle() is freeing all the resources
allocated by virt_viewer_events_add_handle() expect for this GIOChannel.
This commit adds the needed g_io_channel_unref() call to
virt_viewer_events_remove_handle().

Based on
http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=8e95b8d25a3eee6316aff2f83b0c449aaf10984a

Related to: rhbz#1243228
---
 src/virt-viewer-events.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index d36dd3a..6cdc56a 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -239,6 +239,10 @@ virt_viewer_events_remove_handle(int watch)
 data->events = 0;
 }
 
+g_warn_if_fail(data->channel != NULL);
+g_io_channel_unref(data->channel);
+data->channel = NULL;
+
 /* since the actual watch deletion is done asynchronously, a handle_update 
call may
  * reschedule the watch befure it's fully deleted, that's why we need to 
mar it as
  * 'removed' to prevent reuse
-- 
2.4.4

___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list


Re: [virt-tools-list] [virt-viewer][PATCH 2/6] events: remove timeout and handle from arrays

2015-07-17 Thread Christophe Fergeau
On Fri, Jul 17, 2015 at 06:15:19PM +0200, Christophe Fergeau wrote:
> > @@ -115,7 +112,7 @@ int virt_viewer_events_add_handle(int fd,
> >virt_viewer_events_dispatch_handle,
> >data);
> >  
> > -handles[nhandles++] = data;
> > +g_ptr_array_add(handles, data);
> >  
> >  return data->watch;
> >  }
> > @@ -123,10 +120,22 @@ int virt_viewer_events_add_handle(int fd,
> >  static struct virt_viewer_events_handle *
> >  virt_viewer_events_find_handle(int watch)
> 
> any reason for not keeping the guint *idx arg added in the source
> commit?
> 

Ah ok you squashed
https://libvirt.org/git/?p=libvirt-glib.git;a=commitdiff;h=1fb34633ef3b318ea678b775d5e47debc98d2184
in

Christophe


pgpIW0sxKMHav.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH 3/6] glib-compat: Add g_mutex_new()

2015-07-17 Thread Christophe Fergeau
On Fri, Jul 17, 2015 at 04:01:20PM +0200, Fabiano Fidêncio wrote:
> Related to: rhbz#1243228
> ---
>  src/virt-glib-compat.h | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/src/virt-glib-compat.h b/src/virt-glib-compat.h
> index 2c887e9..17c33f0 100644
> --- a/src/virt-glib-compat.h
> +++ b/src/virt-glib-compat.h
> @@ -76,6 +76,10 @@ GByteArray *g_byte_array_new_take (guint8 *data, gsize 
> len);
>  #define G_SOURCE_REMOVE FALSE
>  #endif
>  
> +#if GLIB_CHECK_VERSION(2, 31, 0)
> +#define g_mutex_new() g_new0(GMutex, 1)
> +#endif
> +

ACK

>  G_END_DECLS
>  
>  #endif // _VIRT_GLIB_COMPAT_H
> -- 
> 2.4.4
> 
> ___
> virt-tools-list mailing list
> virt-tools-list@redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list


pgpGG6e0XJBC7.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH 1/6] events: Register event using GOnce to avoid multiple initializations

2015-07-17 Thread Christophe Fergeau
ACK 

On Fri, Jul 17, 2015 at 04:01:18PM +0200, Fabiano Fidêncio wrote:
> Based on
> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=8f8d9ce5238dbcbce40aa04ba55b8c55f97c79c0
> 
> Related to: rhbz#1243228
> ---
>  src/virt-viewer-events.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
> index 3b5a136..6154353 100644
> --- a/src/virt-viewer-events.c
> +++ b/src/virt-viewer-events.c
> @@ -346,14 +346,22 @@ virt_viewer_events_remove_timeout(int timer)
>  return 0;
>  }
>  
> -
> -void virt_viewer_events_register(void) {
> +static gpointer event_register_once(gpointer data G_GNUC_UNUSED)
> +{
>  virEventRegisterImpl(virt_viewer_events_add_handle,
>   virt_viewer_events_update_handle,
>   virt_viewer_events_remove_handle,
>   virt_viewer_events_add_timeout,
>   virt_viewer_events_update_timeout,
>   virt_viewer_events_remove_timeout);
> +
> +return NULL;
> +}
> +
> +void virt_viewer_events_register(void) {
> +static GOnce once = G_ONCE_INIT;
> +
> +g_once(&once, event_register_once, NULL);
>  }
>  
>  /*
> -- 
> 2.4.4
> 
> ___
> virt-tools-list mailing list
> virt-tools-list@redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list


pgpEi3EYn_IyE.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

Re: [virt-tools-list] [virt-viewer][PATCH 2/6] events: remove timeout and handle from arrays

2015-07-17 Thread Christophe Fergeau
Hey,

On Fri, Jul 17, 2015 at 04:01:19PM +0200, Fabiano Fidêncio wrote:
> Based on
> http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=cff5f1c46f4b9661e112b85159fb58ae473a9a89

I'd tend to c&p the initial log too

> 
> Related to: rhbz#1243228
> ---
>  src/virt-viewer-events.c | 97 
> +++-
>  1 file changed, 63 insertions(+), 34 deletions(-)
> 
> diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
> index 6154353..b92506c 100644
> --- a/src/virt-viewer-events.c
> +++ b/src/virt-viewer-events.c
> @@ -39,7 +39,7 @@ struct virt_viewer_events_handle
>  int watch;
>  int fd;
>  int events;
> -int enabled;
> +int removed;

This (and other parts of this commit) are
https://libvirt.org/git/?p=libvirt-glib.git;a=commitdiff;h=3e73e0cee977fb20dd29db3ccfe85b00cc386c43
they should go in a separate commit

>  GIOChannel *channel;
>  guint source;
>  virEventHandleCallback cb;
> @@ -48,8 +48,7 @@ struct virt_viewer_events_handle
>  };
>  
>  static int nextwatch = 1;
> -static unsigned int nhandles = 0;
> -static struct virt_viewer_events_handle **handles = NULL;
> +GPtrArray *handles;

static GPtrArray

>  
>  static gboolean
>  virt_viewer_events_dispatch_handle(GIOChannel *source G_GNUC_UNUSED,
> @@ -86,9 +85,7 @@ int virt_viewer_events_add_handle(int fd,
>  struct virt_viewer_events_handle *data;
>  GIOCondition cond = 0;
>  
> -handles = g_realloc(handles, sizeof(*handles)*(nhandles+1));
> -data = g_malloc(sizeof(*data));
> -memset(data, 0, sizeof(*data));
> +data = g_new0(struct virt_viewer_events_handle, 1);
>  
>  if (events & VIR_EVENT_HANDLE_READABLE)
>  cond |= G_IO_IN;
> @@ -115,7 +112,7 @@ int virt_viewer_events_add_handle(int fd,
>virt_viewer_events_dispatch_handle,
>data);
>  
> -handles[nhandles++] = data;
> +g_ptr_array_add(handles, data);
>  
>  return data->watch;
>  }
> @@ -123,10 +120,22 @@ int virt_viewer_events_add_handle(int fd,
>  static struct virt_viewer_events_handle *
>  virt_viewer_events_find_handle(int watch)

any reason for not keeping the guint *idx arg added in the source
commit?

>  {
> -unsigned int i;
> -for (i = 0 ; i < nhandles ; i++)
> -if (handles[i]->watch == watch)
> -return handles[i];
> +guint i;
> +
> +g_return_val_if_fail(handles != NULL, NULL);
> +
> +for (i = 0; i < handles->len; i++) {
> +struct virt_viewer_events_handle *h = g_ptr_array_index(handles, i);
> +
> +if (h == NULL) {
> +g_warn_if_reached();
> +continue;
> +}
> +
> +if ((h->watch == watch) && !h->removed) {
> +return h;
> +}
> +}
>  
>  return NULL;
>  }
> @@ -182,7 +191,7 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
>  if (data->ff)
>  (data->ff)(data->opaque);
>  
> -free(data);
> +g_ptr_array_remove_fast(handles, data);
>  return FALSE;
>  }
>  
> @@ -199,13 +208,17 @@ virt_viewer_events_remove_handle(int watch)
>  
>  g_debug("Remove handle %d %d", watch, data->fd);
>  
> -if (!data->source)
> -return -1;
> -
> -g_source_remove(data->source);
> -data->source = 0;
> -data->events = 0;
> +if (data->source) {
> +g_source_remove(data->source);
> +data->source = 0;
> +data->events = 0;
> +}
>  
> +/* since the actual watch deletion is done asynchronously, a 
> handle_update call may
> + * reschedule the watch befure it's fully deleted, that's why we need to 
> mar it as

'before' 'mark'


> + * 'removed' to prevent reuse
> + */
> +data->removed = TRUE;
>  g_idle_add(virt_viewer_events_cleanup_handle, data);
>  return 0;
>  }
> @@ -214,6 +227,7 @@ struct virt_viewer_events_timeout
>  {
>  int timer;
>  int interval;
> +int removed;
>  guint source;
>  virEventTimeoutCallback cb;
>  void *opaque;
> @@ -222,8 +236,7 @@ struct virt_viewer_events_timeout
>  
>  
>  static int nexttimer = 1;
> -static unsigned int ntimeouts = 0;
> -static struct virt_viewer_events_timeout **timeouts = NULL;
> +GPtrArray *timeouts;

static

>  
>  static gboolean
>  virt_viewer_events_dispatch_timeout(void *opaque)
> @@ -243,9 +256,7 @@ virt_viewer_events_add_timeout(int interval,
>  {
>  struct virt_viewer_events_timeout *data;
>  
> -timeouts = g_realloc(timeouts, sizeof(*timeouts)*(ntimeouts+1));
> -data = g_malloc(sizeof(*data));
> -memset(data, 0, sizeof(*data));
> +data = g_new0(struct virt_viewer_events_timeout, 1);
>  
>  data->timer = nexttimer++;
>  data->interval = interval;
> @@ -257,7 +268,7 @@ virt_viewer_events_add_timeout(int interval,
>   virt_viewer_events_dispatch_timeout,
>   data);
>  
> -timeouts[ntimeouts++] = data;
> +g_ptr_arra

Re: [virt-tools-list] [virt-viewer][PATCH 0/6] events: "backport" a few patches from libvirt-glib-events to virt-viewer

2015-07-17 Thread Christophe Fergeau
On Fri, Jul 17, 2015 at 04:01:17PM +0200, Fabiano Fidêncio wrote:
> In order to fix rhbz#1243228, I am "backporting" a few fixes from
> libvirt-glib/libvirt-glib-events.c to virt-viewer, as the events
> file used for both seems to be pretty much the same (with the same
> issues as well, sometimes fixed in one, sometimes fixed in the other).

Do you mean virt-viewer has some fixes which are not in libvirt-glib?

Christophe


pgpci7_E4yPQb.pgp
Description: PGP signature
___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

[virt-tools-list] [virt-viewer][PATCH 0/6] events: "backport" a few patches from libvirt-glib-events to virt-viewer

2015-07-17 Thread Fabiano Fidêncio
In order to fix rhbz#1243228, I am "backporting" a few fixes from
libvirt-glib/libvirt-glib-events.c to virt-viewer, as the events
file used for both seems to be pretty much the same (with the same
issues as well, sometimes fixed in one, sometimes fixed in the other).

All patches have a link for the relevant commit in the libvirt-glib.

These patches were already tested by the reporter of rhbz#1243228.

Fabiano Fidêncio (6):
  events: Register event using GOnce to avoid multiple initializations
  events: remove timeout and handle from arrays
  glib-compat: Add g_mutex_new()
  events: protect "handles" and "timeouts" agins concurrent access
  events: Don't create glib IO watch for disabled handles
  events: Allow zero timeouts for timer

 src/virt-glib-compat.h   |   4 +
 src/virt-viewer-events.c | 224 +--
 2 files changed, 163 insertions(+), 65 deletions(-)

-- 
2.4.4

___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list

[virt-tools-list] [virt-viewer][PATCH 5/6] events: Don't create glib IO watch for disabled handles

2015-07-17 Thread Fabiano Fidêncio
It's possible to create a handle to watch for file events which do not
watch for any file event. Such a handle can be enabled later with
gvir_event_handle_update() by setting some conditions to watch for.

When a handle is disabled after it has been created,
gvir_event_handle_update() makes sure it removes the corresponding
gvir_event_handle::source IO watch if any was set.
gvir_event_handle_add() will always create a gvir_event_handle::source
IO watch even if the handle is not watching for any events.

This commit makes consistent by only creating a watch with g_io_add_watch()
when the caller asked to watch for some events.

Based on
http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=d71c143936a35cd6c3f23ae0cbf7f3215d944051

Related to: rhbz#1243228
---
 src/virt-viewer-events.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index ef2c317..c6442f6 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -113,10 +113,12 @@ int virt_viewer_events_add_handle(int fd,
 
 g_debug("Add handle %d %d %p", data->fd, events, data->opaque);
 
-data->source = g_io_add_watch(data->channel,
-  cond,
-  virt_viewer_events_dispatch_handle,
-  data);
+if (events != 0) {
+data->source = g_io_add_watch(data->channel,
+  cond,
+  virt_viewer_events_dispatch_handle,
+  data);
+}
 
 g_ptr_array_add(handles, data);
 
-- 
2.4.4

___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list


[virt-tools-list] [virt-viewer][PATCH 6/6] events: Allow zero timeouts for timer

2015-07-17 Thread Fabiano Fidêncio
In libvirt, it's perfectly possible and widely used to have disabled
timers (timeout=-1) and fire them up 'randomly' with timeout=0.
However, with current mapping into glib mainloop it's not possible
and causing troubles.

Based on
http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=a40a1732e0d53fcc44b8d348cec97152dafd2b88

Related to: rhbz#1243228
---
 src/virt-viewer-events.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index c6442f6..d36dd3a 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -355,7 +355,7 @@ virt_viewer_events_update_timeout(int timer,
 
 if (interval >= 0) {
 if (data->source != 0)
-goto cleanup;
+g_source_remove(data->source);
 
 data->interval = interval;
 data->source = g_timeout_add(data->interval,
-- 
2.4.4

___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list


[virt-tools-list] [virt-viewer][PATCH 2/6] events: remove timeout and handle from arrays

2015-07-17 Thread Fabiano Fidêncio
Based on
http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=cff5f1c46f4b9661e112b85159fb58ae473a9a89

Related to: rhbz#1243228
---
 src/virt-viewer-events.c | 97 +++-
 1 file changed, 63 insertions(+), 34 deletions(-)

diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index 6154353..b92506c 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -39,7 +39,7 @@ struct virt_viewer_events_handle
 int watch;
 int fd;
 int events;
-int enabled;
+int removed;
 GIOChannel *channel;
 guint source;
 virEventHandleCallback cb;
@@ -48,8 +48,7 @@ struct virt_viewer_events_handle
 };
 
 static int nextwatch = 1;
-static unsigned int nhandles = 0;
-static struct virt_viewer_events_handle **handles = NULL;
+GPtrArray *handles;
 
 static gboolean
 virt_viewer_events_dispatch_handle(GIOChannel *source G_GNUC_UNUSED,
@@ -86,9 +85,7 @@ int virt_viewer_events_add_handle(int fd,
 struct virt_viewer_events_handle *data;
 GIOCondition cond = 0;
 
-handles = g_realloc(handles, sizeof(*handles)*(nhandles+1));
-data = g_malloc(sizeof(*data));
-memset(data, 0, sizeof(*data));
+data = g_new0(struct virt_viewer_events_handle, 1);
 
 if (events & VIR_EVENT_HANDLE_READABLE)
 cond |= G_IO_IN;
@@ -115,7 +112,7 @@ int virt_viewer_events_add_handle(int fd,
   virt_viewer_events_dispatch_handle,
   data);
 
-handles[nhandles++] = data;
+g_ptr_array_add(handles, data);
 
 return data->watch;
 }
@@ -123,10 +120,22 @@ int virt_viewer_events_add_handle(int fd,
 static struct virt_viewer_events_handle *
 virt_viewer_events_find_handle(int watch)
 {
-unsigned int i;
-for (i = 0 ; i < nhandles ; i++)
-if (handles[i]->watch == watch)
-return handles[i];
+guint i;
+
+g_return_val_if_fail(handles != NULL, NULL);
+
+for (i = 0; i < handles->len; i++) {
+struct virt_viewer_events_handle *h = g_ptr_array_index(handles, i);
+
+if (h == NULL) {
+g_warn_if_reached();
+continue;
+}
+
+if ((h->watch == watch) && !h->removed) {
+return h;
+}
+}
 
 return NULL;
 }
@@ -182,7 +191,7 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
 if (data->ff)
 (data->ff)(data->opaque);
 
-free(data);
+g_ptr_array_remove_fast(handles, data);
 return FALSE;
 }
 
@@ -199,13 +208,17 @@ virt_viewer_events_remove_handle(int watch)
 
 g_debug("Remove handle %d %d", watch, data->fd);
 
-if (!data->source)
-return -1;
-
-g_source_remove(data->source);
-data->source = 0;
-data->events = 0;
+if (data->source) {
+g_source_remove(data->source);
+data->source = 0;
+data->events = 0;
+}
 
+/* since the actual watch deletion is done asynchronously, a handle_update 
call may
+ * reschedule the watch befure it's fully deleted, that's why we need to 
mar it as
+ * 'removed' to prevent reuse
+ */
+data->removed = TRUE;
 g_idle_add(virt_viewer_events_cleanup_handle, data);
 return 0;
 }
@@ -214,6 +227,7 @@ struct virt_viewer_events_timeout
 {
 int timer;
 int interval;
+int removed;
 guint source;
 virEventTimeoutCallback cb;
 void *opaque;
@@ -222,8 +236,7 @@ struct virt_viewer_events_timeout
 
 
 static int nexttimer = 1;
-static unsigned int ntimeouts = 0;
-static struct virt_viewer_events_timeout **timeouts = NULL;
+GPtrArray *timeouts;
 
 static gboolean
 virt_viewer_events_dispatch_timeout(void *opaque)
@@ -243,9 +256,7 @@ virt_viewer_events_add_timeout(int interval,
 {
 struct virt_viewer_events_timeout *data;
 
-timeouts = g_realloc(timeouts, sizeof(*timeouts)*(ntimeouts+1));
-data = g_malloc(sizeof(*data));
-memset(data, 0, sizeof(*data));
+data = g_new0(struct virt_viewer_events_timeout, 1);
 
 data->timer = nexttimer++;
 data->interval = interval;
@@ -257,7 +268,7 @@ virt_viewer_events_add_timeout(int interval,
  virt_viewer_events_dispatch_timeout,
  data);
 
-timeouts[ntimeouts++] = data;
+g_ptr_array_add(timeouts, data);
 
 g_debug("Add timeout %p %d %p %p %d", data, interval, cb, opaque, 
data->timer);
 
@@ -268,10 +279,22 @@ virt_viewer_events_add_timeout(int interval,
 static struct virt_viewer_events_timeout *
 virt_viewer_events_find_timeout(int timer)
 {
-unsigned int i;
-for (i = 0 ; i < ntimeouts ; i++)
-if (timeouts[i]->timer == timer)
-return timeouts[i];
+guint i;
+
+g_return_val_if_fail(timeouts != NULL, NULL);
+
+for (i = 0; i < timeouts->len; i++) {
+struct virt_viewer_events_timeout *t = g_ptr_array_index(timeouts, i);
+
+if (t == NULL) {
+g_warn_if_reached();
+continue;
+}
+
+if ((t-

[virt-tools-list] [virt-viewer][PATCH 3/6] glib-compat: Add g_mutex_new()

2015-07-17 Thread Fabiano Fidêncio
Related to: rhbz#1243228
---
 src/virt-glib-compat.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/virt-glib-compat.h b/src/virt-glib-compat.h
index 2c887e9..17c33f0 100644
--- a/src/virt-glib-compat.h
+++ b/src/virt-glib-compat.h
@@ -76,6 +76,10 @@ GByteArray *g_byte_array_new_take (guint8 *data, gsize len);
 #define G_SOURCE_REMOVE FALSE
 #endif
 
+#if GLIB_CHECK_VERSION(2, 31, 0)
+#define g_mutex_new() g_new0(GMutex, 1)
+#endif
+
 G_END_DECLS
 
 #endif // _VIRT_GLIB_COMPAT_H
-- 
2.4.4

___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list


[virt-tools-list] [virt-viewer][PATCH 1/6] events: Register event using GOnce to avoid multiple initializations

2015-07-17 Thread Fabiano Fidêncio
Based on
http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=8f8d9ce5238dbcbce40aa04ba55b8c55f97c79c0

Related to: rhbz#1243228
---
 src/virt-viewer-events.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index 3b5a136..6154353 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -346,14 +346,22 @@ virt_viewer_events_remove_timeout(int timer)
 return 0;
 }
 
-
-void virt_viewer_events_register(void) {
+static gpointer event_register_once(gpointer data G_GNUC_UNUSED)
+{
 virEventRegisterImpl(virt_viewer_events_add_handle,
  virt_viewer_events_update_handle,
  virt_viewer_events_remove_handle,
  virt_viewer_events_add_timeout,
  virt_viewer_events_update_timeout,
  virt_viewer_events_remove_timeout);
+
+return NULL;
+}
+
+void virt_viewer_events_register(void) {
+static GOnce once = G_ONCE_INIT;
+
+g_once(&once, event_register_once, NULL);
 }
 
 /*
-- 
2.4.4

___
virt-tools-list mailing list
virt-tools-list@redhat.com
https://www.redhat.com/mailman/listinfo/virt-tools-list


[virt-tools-list] [virt-viewer][PATCH 4/6] events: protect "handles" and "timeouts" agins concurrent access

2015-07-17 Thread Fabiano Fidêncio
Timeout and Handle operations are done from an idle callback. However,
we cannot assume that all libvirt event calls (the callbacks passed to
virEventRegisterImpl) will be done from the mainloop thread. It's thus
possible that a libvirt event call will run a thread while one of the
callbacks runs.
Given that "handles" and "timeouts" arrays are shared among all threads,
we need to make sure we hold the "eventlock" mutex before modifying
them.

Based on
http://libvirt.org/git/?p=libvirt-glib.git;a=commit;h=924178f6b35735458b37d30303fe7bc753dde0b1

Related to: rhbz#1243228
---
 src/virt-viewer-events.c | 109 +++
 1 file changed, 82 insertions(+), 27 deletions(-)

diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index b92506c..ef2c317 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -33,6 +33,9 @@
 #include 
 
 #include "virt-viewer-events.h"
+#include "virt-glib-compat.h"
+
+GMutex *eventlock = NULL;
 
 struct virt_viewer_events_handle
 {
@@ -84,6 +87,9 @@ int virt_viewer_events_add_handle(int fd,
 {
 struct virt_viewer_events_handle *data;
 GIOCondition cond = 0;
+int ret;
+
+g_mutex_lock(eventlock);
 
 data = g_new0(struct virt_viewer_events_handle, 1);
 
@@ -114,7 +120,11 @@ int virt_viewer_events_add_handle(int fd,
 
 g_ptr_array_add(handles, data);
 
-return data->watch;
+ret = data->watch;
+
+g_mutex_unlock(eventlock);
+
+return ret;
 }
 
 static struct virt_viewer_events_handle *
@@ -144,19 +154,22 @@ static void
 virt_viewer_events_update_handle(int watch,
  int events)
 {
-struct virt_viewer_events_handle *data = 
virt_viewer_events_find_handle(watch);
+struct virt_viewer_events_handle *data;
+
+g_mutex_lock(eventlock);
 
-if (!data) {
+data = virt_viewer_events_find_handle(watch);
+if (data == NULL) {
 g_debug("Update for missing handle watch %d", watch);
-return;
+goto cleanup;
 }
 
-if (events) {
+if (events != 0) {
 GIOCondition cond = 0;
 if (events == data->events)
-return;
+goto cleanup;
 
-if (data->source)
+if (data->source != 0)
 g_source_remove(data->source);
 
 cond |= G_IO_HUP;
@@ -170,13 +183,16 @@ virt_viewer_events_update_handle(int watch,
   data);
 data->events = events;
 } else {
-if (!data->source)
-return;
+if (data->source == 0)
+goto cleanup;
 
 g_source_remove(data->source);
 data->source = 0;
 data->events = 0;
 }
+
+cleanup:
+g_mutex_unlock(eventlock);
 }
 
 
@@ -191,7 +207,10 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
 if (data->ff)
 (data->ff)(data->opaque);
 
+g_mutex_lock(eventlock);
 g_ptr_array_remove_fast(handles, data);
+g_mutex_unlock(eventlock);
+
 return FALSE;
 }
 
@@ -199,16 +218,20 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
 static int
 virt_viewer_events_remove_handle(int watch)
 {
-struct virt_viewer_events_handle *data = 
virt_viewer_events_find_handle(watch);
+struct virt_viewer_events_handle *data;
+int ret = -1;
 
-if (!data) {
+g_mutex_lock(eventlock);
+
+data = virt_viewer_events_find_handle(watch);
+if (data == NULL) {
 g_debug("Remove of missing watch %d", watch);
-return -1;
+goto cleanup;
 }
 
 g_debug("Remove handle %d %d", watch, data->fd);
 
-if (data->source) {
+if (data->source != 0) {
 g_source_remove(data->source);
 data->source = 0;
 data->events = 0;
@@ -220,7 +243,12 @@ virt_viewer_events_remove_handle(int watch)
  */
 data->removed = TRUE;
 g_idle_add(virt_viewer_events_cleanup_handle, data);
-return 0;
+ret = 0;
+
+cleanup:
+g_mutex_unlock(eventlock);
+
+return ret;
 }
 
 struct virt_viewer_events_timeout
@@ -255,6 +283,9 @@ virt_viewer_events_add_timeout(int interval,
virFreeCallback ff)
 {
 struct virt_viewer_events_timeout *data;
+int ret;
+
+g_mutex_lock(eventlock);
 
 data = g_new0(struct virt_viewer_events_timeout, 1);
 
@@ -272,7 +303,11 @@ virt_viewer_events_add_timeout(int interval,
 
 g_debug("Add timeout %p %d %p %p %d", data, interval, cb, opaque, 
data->timer);
 
-return data->timer;
+ret = data->timer;
+
+g_mutex_unlock(eventlock);
+
+return ret;
 }
 
 
@@ -304,30 +339,36 @@ static void
 virt_viewer_events_update_timeout(int timer,
   int interval)
 {
-struct virt_viewer_events_timeout *data = 
virt_viewer_events_find_timeout(timer);
+struct virt_viewer_events_timeout *data;
+
+g_mutex_lock(eventlock);
 
-if (!data) {
+data = virt_viewer_events_find_timeout(timer);
+if (data == NULL) {
 g_debug("Update of missing timer