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