1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hc_condition.h"
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
Wait(pthread_cond_t * cond,HcMutex * mutex)22 int Wait(pthread_cond_t* cond, HcMutex* mutex)
23 {
24 if (cond == NULL || mutex == NULL) {
25 return -1;
26 }
27 return -pthread_cond_wait(cond, &mutex->mutex);
28 }
29
Notify(pthread_cond_t * cond)30 void Notify(pthread_cond_t* cond)
31 {
32 if (cond == NULL) {
33 return;
34 }
35 pthread_cond_signal(cond);
36 }
37
HcCondWaitWithoutLock(struct HcConditionT * hcCond)38 int HcCondWaitWithoutLock(struct HcConditionT* hcCond)
39 {
40 if (hcCond == NULL || hcCond->mutex == NULL) {
41 return -1;
42 }
43 if (hcCond->notified) {
44 hcCond->notified = HC_FALSE;
45 return 0;
46 } else {
47 int ret;
48 hcCond->waited = HC_TRUE;
49 ret = Wait(&hcCond->cond, hcCond->mutex);
50 hcCond->waited = HC_FALSE;
51 hcCond->notified = HC_FALSE;
52 return ret;
53 }
54 }
55
HcCondNotifyWithoutLock(struct HcConditionT * hcCond)56 void HcCondNotifyWithoutLock(struct HcConditionT* hcCond)
57 {
58 if (hcCond == NULL || hcCond->mutex == NULL) {
59 return;
60 }
61
62 if (!hcCond->waited) {
63 hcCond->notified = HC_TRUE;
64 } else {
65 hcCond->notified = HC_FALSE;
66 }
67 Notify(&hcCond->cond);
68 }
69
HcCondWait(struct HcConditionT * hcCond)70 int HcCondWait(struct HcConditionT* hcCond)
71 {
72 if (hcCond == NULL) {
73 return -1;
74 }
75 if (hcCond->mutex == NULL) {
76 return -1;
77 }
78
79 hcCond->mutex->lock(hcCond->mutex);
80 if (hcCond->notified) {
81 hcCond->notified = HC_FALSE;
82 hcCond->mutex->unlock(hcCond->mutex);
83 return 0;
84 } else {
85 int ret;
86 hcCond->waited = HC_TRUE;
87 ret = Wait(&hcCond->cond, hcCond->mutex);
88 hcCond->waited = HC_FALSE;
89 hcCond->notified = HC_FALSE;
90 hcCond->mutex->unlock(hcCond->mutex);
91 return ret;
92 }
93 }
94
HcCondNotify(struct HcConditionT * hcCond)95 void HcCondNotify(struct HcConditionT* hcCond)
96 {
97 if (hcCond == NULL || hcCond->mutex == NULL) {
98 return;
99 }
100
101 hcCond->mutex->lock(hcCond->mutex);
102
103 if (!hcCond->waited) {
104 hcCond->notified = HC_TRUE;
105 } else {
106 hcCond->notified = HC_FALSE;
107 }
108 Notify(&hcCond->cond);
109 hcCond->mutex->unlock(hcCond->mutex);
110 }
111
InitHcCond(HcCondition * hcCond,HcMutex * mutex)112 int32_t InitHcCond(HcCondition* hcCond, HcMutex* mutex)
113 {
114 if (hcCond == NULL) {
115 return -1;
116 }
117 hcCond->notified = HC_FALSE;
118 hcCond->waited = HC_FALSE;
119 hcCond->wait = HcCondWait;
120 hcCond->notify = HcCondNotify;
121 hcCond->waitWithoutLock = HcCondWaitWithoutLock;
122 hcCond->notifyWithoutLock = HcCondNotifyWithoutLock;
123
124 pthread_condattr_t attr;
125 pthread_condattr_init(&attr);
126 pthread_cond_init(&hcCond->cond, &attr);
127 pthread_condattr_destroy(&attr);
128
129 if (mutex != NULL) {
130 hcCond->mutex = mutex;
131 hcCond->innerMutex = HC_FALSE;
132 } else {
133 hcCond->mutex = (HcMutex*)HcMalloc(sizeof(HcMutex), 0);
134 if (hcCond->mutex != NULL) {
135 int32_t res = InitHcMutex(hcCond->mutex);
136 if (res != 0) {
137 HcFree(hcCond->mutex);
138 hcCond->mutex = NULL;
139 return res;
140 }
141 hcCond->innerMutex = HC_TRUE;
142 } else {
143 return -1;
144 }
145 }
146 return 0;
147 }
148
DestroyHcCond(HcCondition * hcCond)149 void DestroyHcCond(HcCondition* hcCond)
150 {
151 if (hcCond == NULL) {
152 return;
153 }
154
155 if (hcCond->innerMutex && hcCond->mutex) {
156 DestroyHcMutex(hcCond->mutex);
157 HcFree(hcCond->mutex);
158 hcCond->mutex = NULL;
159 }
160 pthread_cond_destroy(&hcCond->cond);
161 }
162
163 #ifdef __cplusplus
164 }
165 #endif