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