1 /*
2 * libZRTP SDK library, implements the ZRTP secure VoIP protocol.
3 * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
4 * Contact: http://philzimmermann.com
5 * For licensing and other legal details, see the file zrtp_legal.c.
6 *
7 * Viktor Krykun <v.krikun at zfoneproject.com>
8 */
9
10 #include "zrtp.h"
11 #include "queue.h"
12
13 struct zrtp_queue {
14 zrtp_sem_t* size_sem;
15 zrtp_sem_t* main_sem;
16 zrtp_mutex_t* mutex;
17 mlist_t head;
18 uint32_t size;
19 };
20
21
zrtp_test_queue_create(zrtp_queue_t ** queue)22 zrtp_status_t zrtp_test_queue_create(zrtp_queue_t** queue) {
23
24 zrtp_status_t s = zrtp_status_fail;
25 zrtp_queue_t* new_queue = (zrtp_queue_t*) zrtp_sys_alloc(sizeof(zrtp_queue_t));
26 if (! new_queue) {
27 return zrtp_status_fail;
28 }
29 zrtp_memset(new_queue, 0, sizeof(zrtp_queue_t));
30
31 do {
32 s = zrtp_sem_init(&new_queue->size_sem, ZRTP_QUEUE_SIZE, ZRTP_QUEUE_SIZE);
33 if (zrtp_status_ok != s) {
34 break;
35 }
36 s = zrtp_sem_init(&new_queue->main_sem, 0, ZRTP_QUEUE_SIZE);
37 if (zrtp_status_ok != s) {
38 break;
39 }
40
41 s = zrtp_mutex_init(&new_queue->mutex);
42 if (zrtp_status_ok != s) {
43 break;
44 }
45
46 init_mlist(&new_queue->head);
47 new_queue->size = 0;
48
49 s = zrtp_status_ok;
50 } while (0);
51
52 if (zrtp_status_ok != s) {
53 if (new_queue->size_sem) {
54 zrtp_sem_destroy(new_queue->size_sem);
55 }
56 if (new_queue->main_sem) {
57 zrtp_sem_destroy(new_queue->main_sem);
58 }
59 if (new_queue->mutex) {
60 zrtp_mutex_destroy(new_queue->mutex);
61 }
62 }
63
64 *queue = new_queue;
65
66 return s;
67 }
68
zrtp_test_queue_destroy(zrtp_queue_t * queue)69 void zrtp_test_queue_destroy(zrtp_queue_t* queue) {
70 if (queue->size_sem) {
71 zrtp_sem_destroy(queue->size_sem);
72 }
73 if (queue->main_sem) {
74 zrtp_sem_destroy(queue->main_sem);
75 }
76 if (queue->mutex) {
77 zrtp_mutex_destroy(queue->mutex);
78 }
79 }
80
81
zrtp_test_queue_push(zrtp_queue_t * queue,zrtp_queue_elem_t * elem)82 void zrtp_test_queue_push(zrtp_queue_t* queue, zrtp_queue_elem_t* elem) {
83 zrtp_sem_wait(queue->size_sem);
84
85 zrtp_mutex_lock(queue->mutex);
86 mlist_add_tail(&queue->head, &elem->_mlist);
87 queue->size++;
88 zrtp_mutex_unlock(queue->mutex);
89
90 zrtp_sem_post(queue->main_sem);
91 }
92
zrtp_test_queue_pop(zrtp_queue_t * queue)93 zrtp_queue_elem_t* zrtp_test_queue_pop(zrtp_queue_t* queue) {
94 zrtp_queue_elem_t* res = NULL;
95 zrtp_sem_wait(queue->main_sem);
96
97 zrtp_mutex_lock(queue->mutex);
98 if (queue->size) {
99 zrtp_queue_elem_t* elem_cover = mlist_get_struct(zrtp_queue_elem_t, _mlist, queue->head.next);
100 res = elem_cover;
101 mlist_del(queue->head.next);
102
103 queue->size--;
104 zrtp_sem_post(queue->size_sem);
105 } else {
106 zrtp_sem_post(queue->main_sem);
107 }
108 zrtp_mutex_unlock(queue->mutex);
109
110 return res;
111 }
112