1 /*
2  * Copyright (c) 2020-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 #ifndef GRAPHIC_LITE_GRAPHIC_SEMAPHORE_H
17 #define GRAPHIC_LITE_GRAPHIC_SEMAPHORE_H
18 #include "stdbool.h"
19 #include "stdint.h"
20 #ifdef _WIN32
21 #include <windows.h>
22 #elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
23 #include <limits.h>
24 #include <semaphore.h>
25 #else
26 #include "los_sem.h"
27 #endif // WIN32
28 #include "gfx_utils/heap_base.h"
29 
30 namespace OHOS {
31 static constexpr int32_t MAX_SEM_COUNT = 1000; // 1000: max number of semaphore count
32 
33 /** @brief Semaphore adapter for different platform. */
34 class GraphicSemaphore : public HeapBase {
35 public:
36     /** Default constructor */
GraphicSemaphore()37     GraphicSemaphore() : GraphicSemaphore(0, MAX_SEM_COUNT) {}
38 
GraphicSemaphore(int32_t init)39     GraphicSemaphore(int32_t init) : GraphicSemaphore(init, MAX_SEM_COUNT) {}
40 
GraphicSemaphore(int32_t init,int32_t max)41     GraphicSemaphore(int32_t init, int32_t max)
42     {
43         if (max > MAX_SEM_COUNT) {
44             max = MAX_SEM_COUNT;
45         }
46         if (init > max) {
47             init = max;
48         }
49 #ifdef _WIN32
50         sem_ = CreateSemaphore(NULL, init, max, NULL);
51         initFlag_ = (sem_ != nullptr);
52 #elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
53         initFlag_ = (sem_init(&sem_, 0, init) == 0);
54 #else
55         if (max == 1) {
56             initFlag_ = (LOS_BinarySemCreate((uint16_t)init, &sem_) == LOS_OK);
57         } else {
58             initFlag_ = (LOS_SemCreate((uint16_t)init, &sem_) == LOS_OK);
59         }
60 #endif // WIN32
61     }
62 
63     /** Default destructor */
~GraphicSemaphore()64     ~GraphicSemaphore()
65     {
66         if (!initFlag_) {
67             return;
68         }
69 #ifdef _WIN32
70         CloseHandle(sem_);
71 #elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
72         sem_destroy(&sem_);
73 #else
74         LOS_SemDelete(sem_);
75 #endif // WIN32
76     }
77 
78     /** Increases the count of the specified semaphore object by a specified amount. */
Notify()79     inline bool Notify()
80     {
81         if (!initFlag_) {
82             return false;
83         }
84 #ifdef _WIN32
85         return ReleaseSemaphore(sem_, 1, NULL);
86 #elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
87         return (sem_post(&sem_) == 0);
88 #else
89         return (LOS_SemPost(sem_) == LOS_OK);
90 #endif // WIN32
91     }
92 
93     /** Waits until the specified object is in the signaled state. */
Wait()94     inline bool Wait()
95     {
96         if (!initFlag_) {
97             return false;
98         }
99 #ifdef _WIN32
100         return (WaitForSingleObject(sem_, INFINITE) == WAIT_OBJECT_0);
101 #elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
102         return (sem_wait(&sem_) == 0);
103 #else
104         return (LOS_SemPend(sem_, LOS_WAIT_FOREVER) == LOS_OK);
105 #endif // WIN32
106     }
107 
108 private:
109     bool initFlag_;
110 #ifdef _WIN32
111     HANDLE sem_;
112 #elif defined __linux__ || defined __LITEOS__ || defined __APPLE__
113     sem_t sem_;
114 #else
115     uint32_t sem_;
116 #endif // WIN32
117 };
118 } // namespace OHOS
119 #endif // GRAPHIC_LITE_GRAPHIC_SEMAPHORE_H
120