Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20141111' into staging
[qemu-kvm.git] / libcacard / event.c
blob4c551e4e388164d94e5e9d7d30ca58c1886a46ce
1 /*
2 * event queue implementation.
4 * This code is licensed under the GNU LGPL, version 2.1 or later.
5 * See the COPYING.LIB file in the top-level directory.
6 */
8 #include "qemu-common.h"
10 #include "vcard.h"
11 #include "vreader.h"
12 #include "vevent.h"
14 VEvent *
15 vevent_new(VEventType type, VReader *reader, VCard *card)
17 VEvent *new_vevent;
19 new_vevent = g_new(VEvent, 1);
20 new_vevent->next = NULL;
21 new_vevent->type = type;
22 new_vevent->reader = vreader_reference(reader);
23 new_vevent->card = vcard_reference(card);
25 return new_vevent;
28 void
29 vevent_delete(VEvent *vevent)
31 if (vevent == NULL) {
32 return;
34 vreader_free(vevent->reader);
35 vcard_free(vevent->card);
36 g_free(vevent);
40 * VEvent queue management
43 static VEvent *vevent_queue_head;
44 static VEvent *vevent_queue_tail;
45 static CompatGMutex vevent_queue_lock;
46 static CompatGCond vevent_queue_condition;
48 void vevent_queue_init(void)
50 vevent_queue_head = vevent_queue_tail = NULL;
53 void
54 vevent_queue_vevent(VEvent *vevent)
56 vevent->next = NULL;
57 g_mutex_lock(&vevent_queue_lock);
58 if (vevent_queue_head) {
59 assert(vevent_queue_tail);
60 vevent_queue_tail->next = vevent;
61 } else {
62 vevent_queue_head = vevent;
64 vevent_queue_tail = vevent;
65 g_cond_signal(&vevent_queue_condition);
66 g_mutex_unlock(&vevent_queue_lock);
69 /* must have lock */
70 static VEvent *
71 vevent_dequeue_vevent(void)
73 VEvent *vevent = NULL;
74 if (vevent_queue_head) {
75 vevent = vevent_queue_head;
76 vevent_queue_head = vevent->next;
77 vevent->next = NULL;
79 return vevent;
82 VEvent *vevent_wait_next_vevent(void)
84 VEvent *vevent;
86 g_mutex_lock(&vevent_queue_lock);
87 while ((vevent = vevent_dequeue_vevent()) == NULL) {
88 g_cond_wait(&vevent_queue_condition, &vevent_queue_lock);
90 g_mutex_unlock(&vevent_queue_lock);
91 return vevent;
94 VEvent *vevent_get_next_vevent(void)
96 VEvent *vevent;
98 g_mutex_lock(&vevent_queue_lock);
99 vevent = vevent_dequeue_vevent();
100 g_mutex_unlock(&vevent_queue_lock);
101 return vevent;