Add qemu 2.4.0
[kvmfornfv.git] / qemu / libcacard / event.c
1 /*
2  * event queue implementation.
3  *
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  */
7
8 #include "glib-compat.h"
9
10 #include "vcard.h"
11 #include "vreader.h"
12 #include "vevent.h"
13
14 VEvent *
15 vevent_new(VEventType type, VReader *reader, VCard *card)
16 {
17     VEvent *new_vevent;
18
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);
24
25     return new_vevent;
26 }
27
28 void
29 vevent_delete(VEvent *vevent)
30 {
31     if (vevent == NULL) {
32         return;
33     }
34     vreader_free(vevent->reader);
35     vcard_free(vevent->card);
36     g_free(vevent);
37 }
38
39 /*
40  * VEvent queue management
41  */
42
43 static VEvent *vevent_queue_head;
44 static VEvent *vevent_queue_tail;
45 static CompatGMutex vevent_queue_lock;
46 static CompatGCond vevent_queue_condition;
47
48 void vevent_queue_init(void)
49 {
50     vevent_queue_head = vevent_queue_tail = NULL;
51 }
52
53 void
54 vevent_queue_vevent(VEvent *vevent)
55 {
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;
63     }
64     vevent_queue_tail = vevent;
65     g_cond_signal(&vevent_queue_condition);
66     g_mutex_unlock(&vevent_queue_lock);
67 }
68
69 /* must have lock */
70 static VEvent *
71 vevent_dequeue_vevent(void)
72 {
73     VEvent *vevent = NULL;
74     if (vevent_queue_head) {
75         vevent = vevent_queue_head;
76         vevent_queue_head = vevent->next;
77         vevent->next = NULL;
78     }
79     return vevent;
80 }
81
82 VEvent *vevent_wait_next_vevent(void)
83 {
84     VEvent *vevent;
85
86     g_mutex_lock(&vevent_queue_lock);
87     while ((vevent = vevent_dequeue_vevent()) == NULL) {
88         g_cond_wait(&vevent_queue_condition, &vevent_queue_lock);
89     }
90     g_mutex_unlock(&vevent_queue_lock);
91     return vevent;
92 }
93
94 VEvent *vevent_get_next_vevent(void)
95 {
96     VEvent *vevent;
97
98     g_mutex_lock(&vevent_queue_lock);
99     vevent = vevent_dequeue_vevent();
100     g_mutex_unlock(&vevent_queue_lock);
101     return vevent;
102 }
103