/* * event queue implementation. * * This code is licensed under the GNU LGPL, version 2.1 or later. * See the COPYING.LIB file in the top-level directory. */ #include "qemu-common.h" #include "vcard.h" #include "vreader.h" #include "vevent.h" VEvent * vevent_new(VEventType type, VReader *reader, VCard *card) { VEvent *new_vevent; new_vevent = g_new(VEvent, 1); new_vevent->next = NULL; new_vevent->type = type; new_vevent->reader = vreader_reference(reader); new_vevent->card = vcard_reference(card); return new_vevent; } void vevent_delete(VEvent *vevent) { if (vevent == NULL) { return; } vreader_free(vevent->reader); vcard_free(vevent->card); g_free(vevent); } /* * VEvent queue management */ static VEvent *vevent_queue_head; static VEvent *vevent_queue_tail; static CompatGMutex vevent_queue_lock; static CompatGCond vevent_queue_condition; void vevent_queue_init(void) { vevent_queue_head = vevent_queue_tail = NULL; } void vevent_queue_vevent(VEvent *vevent) { vevent->next = NULL; g_mutex_lock(&vevent_queue_lock); if (vevent_queue_head) { assert(vevent_queue_tail); vevent_queue_tail->next = vevent; } else { vevent_queue_head = vevent; } vevent_queue_tail = vevent; g_cond_signal(&vevent_queue_condition); g_mutex_unlock(&vevent_queue_lock); } /* must have lock */ static VEvent * vevent_dequeue_vevent(void) { VEvent *vevent = NULL; if (vevent_queue_head) { vevent = vevent_queue_head; vevent_queue_head = vevent->next; vevent->next = NULL; } return vevent; } VEvent *vevent_wait_next_vevent(void) { VEvent *vevent; g_mutex_lock(&vevent_queue_lock); while ((vevent = vevent_dequeue_vevent()) == NULL) { g_cond_wait(&vevent_queue_condition, &vevent_queue_lock); } g_mutex_unlock(&vevent_queue_lock); return vevent; } VEvent *vevent_get_next_vevent(void) { VEvent *vevent; g_mutex_lock(&vevent_queue_lock); vevent = vevent_dequeue_vevent(); g_mutex_unlock(&vevent_queue_lock); return vevent; }