On Wed, May 30, 2012 at 12:02:36PM +0300, Yonit Halperin wrote: > Signed-off-by: Yonit Halperin <yhalperi@xxxxxxxxxx> One empty line that snuck in below. > --- > input.c | 2 +- > migration.c | 2 +- > notify.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- > notify.h | 55 ++++++++++++++++++++++++++++++++++++--- > qemu-timer.c | 2 +- > vl.c | 2 +- > 6 files changed, 129 insertions(+), 13 deletions(-) > > diff --git a/input.c b/input.c > index 6968b31..06f6f9f 100644 > --- a/input.c > +++ b/input.c > @@ -274,5 +274,5 @@ void qemu_add_mouse_mode_change_notifier(Notifier *notify) > > void qemu_remove_mouse_mode_change_notifier(Notifier *notify) > { > - notifier_remove(notify); > + notifier_remove(¬ify->base); > } > diff --git a/migration.c b/migration.c > index 3f485d3..acaf293 100644 > --- a/migration.c > +++ b/migration.c > @@ -320,7 +320,7 @@ void add_migration_state_change_notifier(Notifier *notify) > > void remove_migration_state_change_notifier(Notifier *notify) > { > - notifier_remove(notify); > + notifier_remove(¬ify->base); > } > > bool migration_is_active(MigrationState *s) > diff --git a/notify.c b/notify.c > index 12282a6..dde190e 100644 > --- a/notify.c > +++ b/notify.c > @@ -19,23 +19,94 @@ > void notifier_list_init(NotifierList *list) > { > QLIST_INIT(&list->notifiers); > + QLIST_INIT(&list->wait_notifiers); > } > > void notifier_list_add(NotifierList *list, Notifier *notifier) > { > - QLIST_INSERT_HEAD(&list->notifiers, notifier, node); > + notifier->base.type = NOTIFIER_TYPE_SYNC; > + QLIST_INSERT_HEAD(&list->notifiers, ¬ifier->base, node); > } > > -void notifier_remove(Notifier *notifier) > +void notifier_list_add_async(NotifierList *list, AsyncNotifier *notifier) > +{ > + notifier->base.type = NOTIFIER_TYPE_ASYNC; > + QLIST_INSERT_HEAD(&list->notifiers, ¬ifier->base, node); > +} > + > +void notifier_remove(BaseNotifier *notifier) > { > QLIST_REMOVE(notifier, node); > } > > +static void notified_complete_cb(AsyncNotifier *notifier, void *opaque) > +{ > + NotifierList *list = opaque; > + > + QLIST_REMOVE(notifier, wait_node); > + > + if (QLIST_EMPTY(&list->wait_notifiers) && !list->during_notify) { > + if (list->complete_cb) { > + list->complete_cb(list->complete_opaque); > + } > + } > +} > + > void notifier_list_notify(NotifierList *list, void *data) > { > - Notifier *notifier, *next; > + BaseNotifier *notifier, *next; > + bool async = false; > + > + if (notifier_list_async_waiting(list)) { > + AsyncNotifier *wait_notifier, *wait_next; > + > + fprintf(stderr, "%s: previous notify hasn't completed\n", __func__); > + QLIST_FOREACH_SAFE(wait_notifier, &list->wait_notifiers, > + wait_node, wait_next) { > + QLIST_REMOVE(wait_notifier, wait_node); > + } > + Unnecessary empty line. > + } > + > + list->during_notify = true; > > QLIST_FOREACH_SAFE(notifier, &list->notifiers, node, next) { > - notifier->notify(notifier, data); > + switch (notifier->type) { > + case NOTIFIER_TYPE_SYNC: > + { > + Notifier *sync_notifier; > + > + sync_notifier = container_of(notifier, Notifier, base); > + sync_notifier->notify(sync_notifier, data); > + break; > + } > + case NOTIFIER_TYPE_ASYNC: > + { > + AsyncNotifier *async_notifier; > + > + async = true; > + async_notifier = container_of(notifier, AsyncNotifier, base); > + QLIST_INSERT_HEAD(&list->wait_notifiers, > + async_notifier, > + wait_node); > + async_notifier->notify_async(async_notifier, data, > + notified_complete_cb, list); > + break; > + } > + default: > + fprintf(stderr, "%s: invalid notifier type %d\n", __func__, > + notifier->type); > + break; > + } > } > + > + list->during_notify = false; > + if ((!async || !notifier_list_async_waiting(list)) && list->complete_cb) { > + list->complete_cb(list->complete_opaque); > + } > +} > + > +bool notifier_list_async_waiting(NotifierList *list) > +{ > + return !QLIST_EMPTY(&list->wait_notifiers); > } > diff --git a/notify.h b/notify.h > index 03cf26c..8660920 100644 > --- a/notify.h > +++ b/notify.h > @@ -16,28 +16,73 @@ > > #include "qemu-queue.h" > > +typedef enum NotifierType { > + NOTIFIER_TYPE_NONE, > + NOTIFIER_TYPE_SYNC, > + NOTIFIER_TYPE_ASYNC, > +} NotifierType; > + > +typedef struct BaseNotifier BaseNotifier; > + > +struct BaseNotifier { > + QLIST_ENTRY(BaseNotifier) node; > + NotifierType type; > +}; > typedef struct Notifier Notifier; > > struct Notifier > { > + BaseNotifier base; > void (*notify)(Notifier *notifier, void *data); > - QLIST_ENTRY(Notifier) node; > }; > > +typedef struct AsyncNotifier AsyncNotifier; > +typedef void (NotifiedCompletionFunc)(AsyncNotifier *notifier, void *opaque); > + > +struct AsyncNotifier { > + BaseNotifier base; > + void (*notify_async)(AsyncNotifier *notifier, void *data, > + NotifiedCompletionFunc *complete_cb, void *cb_data); > + QLIST_ENTRY(AsyncNotifier) wait_node; > +}; > + > +typedef void (NotifyListCompletion)(void *opaque); > + > typedef struct NotifierList > { > - QLIST_HEAD(, Notifier) notifiers; > + QLIST_HEAD(, BaseNotifier) notifiers; > + > + NotifyListCompletion *complete_cb; > + void *complete_opaque; > + > + QLIST_HEAD(, AsyncNotifier) wait_notifiers; > + bool during_notify; > } NotifierList; > > -#define NOTIFIER_LIST_INITIALIZER(head) \ > - { QLIST_HEAD_INITIALIZER((head).notifiers) } > +#define NOTIFIER_LIST_INITIALIZER(head) \ > + { QLIST_HEAD_INITIALIZER((head).notifiers), \ > + NULL, \ > + NULL, \ > + QLIST_HEAD_INITIALIZER((head).wait_notifiers) \ > + } > > +#define ASYNC_NOTIFIER_LIST_INITIALIZER(head, cb, cb_data) \ > + { QLIST_HEAD_INITIALIZER((head).notifiers), \ > + cb, \ > + cb_data, \ > + QLIST_HEAD_INITIALIZER((head).wait_notifiers) \ > + } > void notifier_list_init(NotifierList *list); > > void notifier_list_add(NotifierList *list, Notifier *notifier); > +void notifier_list_add_async(NotifierList *list, AsyncNotifier *notifier); > > -void notifier_remove(Notifier *notifier); > +void notifier_remove(BaseNotifier *notifier); > > void notifier_list_notify(NotifierList *list, void *data); > > +/* returns true when there are async notifiers that still hasn't > + * called complete_cb for the last notification */ > +bool notifier_list_async_waiting(NotifierList *list); > + > #endif > diff --git a/qemu-timer.c b/qemu-timer.c > index de98977..2b2f84a 100644 > --- a/qemu-timer.c > +++ b/qemu-timer.c > @@ -430,7 +430,7 @@ void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) > > void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) > { > - notifier_remove(notifier); > + notifier_remove(¬ifier->base); > } > > void init_clocks(void) > diff --git a/vl.c b/vl.c > index 23ab3a3..646b16b 100644 > --- a/vl.c > +++ b/vl.c > @@ -2183,7 +2183,7 @@ void qemu_add_exit_notifier(Notifier *notify) > > void qemu_remove_exit_notifier(Notifier *notify) > { > - notifier_remove(notify); > + notifier_remove(¬ify->base); > } > > static void qemu_run_exit_notifiers(void) > -- > 1.7.7.6 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel