1 /*
2 * Copyright (C) 2022 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 #include "synchronize_event.h"
16
17 #include <cerrno>
18 #include <cstring>
19
20 #include "loghelper.h"
21
22 namespace OHOS {
23 namespace NFC {
24 static const int MILLISECOND_PER_SECOND = 1000;
25 static const int NANOSECOND_PER_MILLISECOND = 1000000;
26 static const int NANOSECOND_PER_SECOND = 1000000000;
27
SynchronizeEvent()28 SynchronizeEvent::SynchronizeEvent()
29 {
30 pthread_mutex_init(&lock_, nullptr);
31 pthread_condattr_t attr;
32 pthread_condattr_init(&attr);
33 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
34 pthread_cond_init(&cond_, &attr);
35 }
36
~SynchronizeEvent()37 SynchronizeEvent::~SynchronizeEvent()
38 {
39 pthread_mutex_destroy(&lock_);
40 pthread_cond_destroy(&cond_);
41 }
42
Start()43 void SynchronizeEvent::Start()
44 {
45 int res = pthread_mutex_lock(&lock_);
46 if (res != 0) {
47 DebugLog("SynchronizeEvent::start: fail lock; error=0x%{public}X", res);
48 }
49 }
50
End()51 void SynchronizeEvent::End()
52 {
53 int res = pthread_mutex_unlock(&lock_);
54 if (res != 0) {
55 DebugLog("SynchronizeEvent::end: fail unlock; error=0x%{public}X", res);
56 }
57 }
58
Wait()59 void SynchronizeEvent::Wait()
60 {
61 int const res = pthread_cond_wait(&cond_, &lock_);
62 if (res) {
63 DebugLog("CondVar::wait: fail wait; error=0x%{public}X", res);
64 }
65 }
66
Wait(long ms)67 bool SynchronizeEvent::Wait(long ms)
68 {
69 bool retVal = false;
70 struct timespec absoluteTime;
71 clock_gettime(CLOCK_MONOTONIC, &absoluteTime);
72
73 absoluteTime.tv_sec += ms / MILLISECOND_PER_SECOND;
74 long ns = absoluteTime.tv_nsec + ((ms % MILLISECOND_PER_SECOND) * NANOSECOND_PER_MILLISECOND);
75 if (ns > NANOSECOND_PER_SECOND) {
76 absoluteTime.tv_sec++;
77 absoluteTime.tv_nsec = ns - NANOSECOND_PER_SECOND;
78 } else {
79 absoluteTime.tv_nsec = ns;
80 }
81
82 int waitResult = pthread_cond_timedwait(&cond_, &lock_, &absoluteTime);
83 if ((waitResult != 0) && (waitResult != ETIMEDOUT)) {
84 DebugLog("SynchronizeEvent::wait: fail timed wait; error=0x%{public}X", waitResult);
85 }
86 retVal = (waitResult == 0); // waited successfully
87 return retVal;
88 }
89
NotifyOne()90 void SynchronizeEvent::NotifyOne()
91 {
92 int const res = pthread_cond_signal(&cond_);
93 if (res) {
94 DebugLog("SynchronizeEvent::notifyOne: fail signal; error=0x%{public}X", res);
95 }
96 }
97 } // namespace NFC
98 } // namespace OHOS
99