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
30namespace OHOS {
31static constexpr int32_t MAX_SEM_COUNT = 1000; // 1000: max number of semaphore count
32
33/** @brief Semaphore adapter for different platform. */
34class GraphicSemaphore : public HeapBase {
35public:
36    /** Default constructor */
37    GraphicSemaphore() : GraphicSemaphore(0, MAX_SEM_COUNT) {}
38
39    GraphicSemaphore(int32_t init) : GraphicSemaphore(init, MAX_SEM_COUNT) {}
40
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 */
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. */
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. */
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
108private:
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