qemu/libcacard/event.c

104 lines
2.1 KiB
C

/*
* 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 "glib-compat.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;
}