1 /*
2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "blocking_queue.h"
10
HdfBlockingQueueInit(struct HdfBlockingQueue * queue)11 void HdfBlockingQueueInit(struct HdfBlockingQueue *queue)
12 {
13 HdfSListInit(&queue->list);
14 OsalSemInit(&queue->sem);
15 OsalMutexInit(&queue->mutex);
16 }
17
HdfBlockingQueueDestroy(struct HdfBlockingQueue * queue)18 void HdfBlockingQueueDestroy(struct HdfBlockingQueue *queue)
19 {
20 HdfSListInit(&queue->list);
21 OsalSemDestroy(&queue->sem);
22 OsalMutexDestroy(&queue->mutex);
23 }
24
HdfBlockingQueueFlush(struct HdfBlockingQueue * queue)25 void HdfBlockingQueueFlush(struct HdfBlockingQueue *queue)
26 {
27 OsalMutexLock(&queue->mutex);
28 HdfSListFlush(&queue->list, HdfSListRemove);
29 OsalMutexUnlock(&queue->mutex);
30 OsalSemPost(&queue->sem);
31 }
32
HdfBlockingQueueTake(struct HdfBlockingQueue * queue)33 void *HdfBlockingQueueTake(struct HdfBlockingQueue *queue)
34 {
35 void *data = HdfBlockingQueueGet(queue);
36 if (data == NULL) {
37 OsalSemWait(&queue->sem, OSAL_WAIT_FOREVER);
38 data = HdfBlockingQueueGet(queue);
39 }
40 return data;
41 }
42
HdfBlockingQueueGet(struct HdfBlockingQueue * queue)43 void *HdfBlockingQueueGet(struct HdfBlockingQueue *queue)
44 {
45 void *data = NULL;
46 struct HdfSListEntry *entry;
47 OsalMutexLock(&queue->mutex);
48 entry = (struct HdfSListEntry *)HdfSListPeek(&queue->list);
49 OsalMutexUnlock(&queue->mutex);
50 if (entry != NULL) {
51 data = entry->data;
52 HdfSListEntryFree(entry);
53 }
54 return data;
55 }
56
57
HdfBlockingQueueFind(struct HdfBlockingQueue * queue,long matchKey,SlList_Comparer comparer)58 void *HdfBlockingQueueFind(struct HdfBlockingQueue *queue, long matchKey, SlList_Comparer comparer)
59 {
60 void *matchData = NULL;
61 struct HdfSListIterator it;
62 struct HdfSListEntry *entry = NULL;
63 if (comparer == NULL) {
64 return NULL;
65 }
66 OsalMutexLock(&queue->mutex);
67 HdfSListIteratorInit(&it, &queue->list);
68 while (HdfSListIteratorHasNext(&it)) {
69 entry = (struct HdfSListEntry *) HdfSListIteratorNext(&it);
70 if (comparer(matchKey, entry->data)) {
71 matchData = entry->data;
72 break;
73 }
74 }
75 OsalMutexUnlock(&queue->mutex);
76 return matchData;
77 }
78
HdfBlockingQueueRemove(struct HdfBlockingQueue * queue,void * data)79 void HdfBlockingQueueRemove(struct HdfBlockingQueue *queue, void *data)
80 {
81 bool targetListChanged = false;
82 struct HdfSListIterator it;
83 struct HdfSListEntry *entry = NULL;
84 OsalMutexLock(&queue->mutex);
85 HdfSListIteratorInit(&it, &queue->list);
86 while (HdfSListIteratorHasNext(&it)) {
87 entry = (struct HdfSListEntry *)HdfSListIteratorNext(&it);
88 if (entry->data == data) {
89 HdfSListIteratorRemove(&it);
90 HdfSListEntryFree(entry);
91 targetListChanged = true;
92 break;
93 }
94 }
95 OsalMutexUnlock(&queue->mutex);
96 if (targetListChanged) {
97 OsalSemPost(&queue->sem);
98 }
99 }
100
HdfBlockingQueuePoll(struct HdfBlockingQueue * queue,long timeout)101 void *HdfBlockingQueuePoll(struct HdfBlockingQueue *queue, long timeout)
102 {
103 void *data = HdfBlockingQueueGet(queue);
104 if (data == NULL) {
105 OsalSemWait(&queue->sem, timeout);
106 data = HdfBlockingQueueGet(queue);
107 }
108 return data;
109 }
110
HdfBlockingQueueOffer(struct HdfBlockingQueue * queue,void * val,long timeout)111 int HdfBlockingQueueOffer(struct HdfBlockingQueue *queue, void *val, long timeout)
112 {
113 struct HdfSListEntry *entry = NULL;
114 if (OsalSemWait(&queue->sem, timeout) != 0) {
115 return -1;
116 }
117 entry = HdfSListEntryNew(val);
118 if (entry != NULL) {
119 OsalMutexLock(&queue->mutex);
120 HdfSListAddTail(&queue->list, &entry->node);
121 OsalMutexUnlock(&queue->mutex);
122 }
123 OsalSemPost(&queue->sem);
124 }
125
126