• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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