84 lines
1.7 KiB
C++
84 lines
1.7 KiB
C++
/*
|
||
* Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
|
||
*
|
||
* This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
|
||
*
|
||
* Use of this source code is governed by MIT license that can be found in the
|
||
* LICENSE file in the root of the source tree. All contributing project authors
|
||
* may be found in the AUTHORS file in the root of the source tree.
|
||
*/
|
||
|
||
#ifndef SEMAPHORE_H_
|
||
#define SEMAPHORE_H_
|
||
|
||
/*
|
||
* 目前发现信号量在32位的系统上有问题,
|
||
* 休眠的线程无法被正常唤醒,先禁用之
|
||
#if defined(__linux__)
|
||
#include <semaphore.h>
|
||
#define HAVE_SEM
|
||
#endif //HAVE_SEM
|
||
*/
|
||
|
||
#include <mutex>
|
||
#include <condition_variable>
|
||
|
||
namespace toolkit {
|
||
|
||
class semaphore {
|
||
public:
|
||
explicit semaphore(size_t initial = 0) {
|
||
#if defined(HAVE_SEM)
|
||
sem_init(&_sem, 0, initial);
|
||
#else
|
||
_count = 0;
|
||
#endif
|
||
}
|
||
|
||
~semaphore() {
|
||
#if defined(HAVE_SEM)
|
||
sem_destroy(&_sem);
|
||
#endif
|
||
}
|
||
|
||
void post(size_t n = 1) {
|
||
#if defined(HAVE_SEM)
|
||
while (n--) {
|
||
sem_post(&_sem);
|
||
}
|
||
#else
|
||
std::unique_lock<std::recursive_mutex> lock(_mutex);
|
||
_count += n;
|
||
if (n == 1) {
|
||
_condition.notify_one();
|
||
} else {
|
||
_condition.notify_all();
|
||
}
|
||
#endif
|
||
}
|
||
|
||
void wait() {
|
||
#if defined(HAVE_SEM)
|
||
sem_wait(&_sem);
|
||
#else
|
||
std::unique_lock<std::recursive_mutex> lock(_mutex);
|
||
while (_count == 0) {
|
||
_condition.wait(lock);
|
||
}
|
||
--_count;
|
||
#endif
|
||
}
|
||
|
||
private:
|
||
#if defined(HAVE_SEM)
|
||
sem_t _sem;
|
||
#else
|
||
size_t _count;
|
||
std::recursive_mutex _mutex;
|
||
std::condition_variable_any _condition;
|
||
#endif
|
||
};
|
||
|
||
} /* namespace toolkit */
|
||
#endif /* SEMAPHORE_H_ */
|