[Libvirt-cim] [PATCH] [RFC] Implement libvirt event callback management

Kaitlin Rupert kaitlin at linux.vnet.ibm.com
Tue Aug 18 23:24:34 UTC 2009


Hi Hollis,

I applied your patch and the patches Richard submitted to do some 
testing. I noticed a few issues commented below...


> +/* Delete all watches marked for deletion. */
> +static void event_watch_free_deleted(void)
> +{
> +        struct watch *cur;
> +        struct watch **link;
> +
> +        CU_DEBUG("%s", __func__);
> +
> +        pthread_mutex_lock(&watch_list_mutex);
> +
> +        cur = watch_list; 
> +        link = &watch_list;
> +        while (cur != NULL) {
> +                struct watch *next = cur->next;
> +
> +                if (cur->deleted) {
> +                        *link = next;
> +
> +                        cur->ff(cur->opaque);

I'm seeing a seg fault here because once we reach this point, cur is NULL.

> +                        free(cur);
> +                        watch_count--;
> +                } else
> +                        link = &cur->next;
> +
> +                cur = next;
> +        }
> +
> +        pthread_mutex_unlock(&watch_list_mutex);
> +}
> +

> +/* One thread to watch all fds for all events for all libvirt threads. */
> +static void *event_thread(void *ptr)
> +{
> +        while (1) {
> +                struct watch *cur;
> +                struct pollfd *pollfds;
> +                struct pollfd *pollfd;
> +                int timeout;
> +                int i;
> +
> +                pollfds = malloc(sizeof(struct pollfd) * watch_count);
> +
> +                /* fill in pollfds array from our watch list */
> +                for (pollfd = &pollfds[0], cur = watch_list;
> +                     cur != NULL;
> +                     pollfd++, cur = cur->next) {
> +                        pollfd->fd = cur->fd;
> +                        pollfd->events = libvirt_to_poll_events(cur->events);
> +                }
> +
> +                timeout = event_next_timeout();
> +
> +                poll(pollfds, watch_count, timeout);
> +
> +                /* invoke callbacks */
> +                for (i = 0; i < watch_count; i++)
> +                        for (cur = watch_list; cur != NULL; cur = cur->next)
> +                                if (cur->fd == pollfds[i].fd

When I generate a event, poll never seems to catch it.  I tried forcing 
this by changing the timeout value to a minute.  And then generating the 
event.  I can see from the libvirt debug that the event has been generated:

15:00:34.232: debug : virEventRunOnce:567 : Poll got 1 event
15:00:34.239: debug : virEventDispatchHandles:450 : Dispatch n=2 f=8 w=3 
e=1 0x7f2a57d6e6b0

In the eventAddHandle() call, we have:

event.c(75): eventAddHandle
event.c(82): ++++++++++++++watch->id is 0
event.c(84): ++++++++++++++watch->fd is 11
event.c(86): ++++++++++++++watch->events is 1
event.c(88): ++++++++++++++watch->cb is 0x6b8f4c0, cb is 0x6b8f4c0
event.c(90): ++++++++++++++watch->opaque is 0x7fffdc014900


I haven't tracked down what is happening here.


> +                                    && !cur->deleted) {
> +                                        invoke_callback(cur, &pollfds[i]);
> +                                        break;
> +                                }
> +
> +                free(pollfds);
> +
> +                event_watch_free_deleted();
> +                event_timer_free_deleted();
> +        }
> +
> +        return NULL;
> +}
> +
> +void init_events(void)
> +{
> +        static pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
> +
> +        CU_DEBUG("%s", __func__);
> +
> +        pthread_mutex_lock(&thread_mutex);
> +
> +        if (!watch_thread_id) {
> +                virEventRegisterImpl(eventAddHandle,
> +                                     eventUpdateHandle,
> +                                     eventRemoveHandle,
> +                                     eventAddTimeout,
> +                                     eventUpdateTimeout,
> +                                     eventRemoveTimeout);
> +
> +                pthread_create(&watch_thread_id, NULL, event_thread, NULL);
> +        }
> +
> +        pthread_mutex_unlock(&thread_mutex);
> +}

-- 
Kaitlin Rupert
IBM Linux Technology Center
kaitlin at linux.vnet.ibm.com




More information about the Libvirt-cim mailing list