//
|
// Created by pans on 19-1-13.
|
//
|
|
#ifndef GB28181SDK_GLOBALSIGNALWAITLOCK_H
|
#define GB28181SDK_GLOBALSIGNALWAITLOCK_H
|
|
#include <iostream>
|
#include <Debug.h>
|
#include <basic/util/thread/RWLock.hpp>
|
|
//#define TryCath(CODE) try { \
|
//CODE } catch (std::exception ex) { \
|
//ERR(ex.what()); \
|
//return false; \
|
//} return true;
|
|
#define gSignalLock GlobalSignalWaitLock::getInstance()
|
|
//#todo 记录每个信号的wait状态,避免某个信号还在使用却将其删除的情况
|
class SignalLock {
|
public:
|
SignalLock() : m_signal_cond_mutex(PTHREAD_MUTEX_INITIALIZER),
|
m_signal_cond(PTHREAD_COND_INITIALIZER) {
|
|
}
|
|
virtual ~SignalLock() {
|
|
}
|
|
bool wait() {
|
pthread_mutex_lock(&m_signal_cond_mutex);
|
pthread_cond_wait(&m_signal_cond, &m_signal_cond_mutex);
|
pthread_mutex_unlock(&m_signal_cond_mutex);
|
}
|
|
bool emit() {
|
pthread_cond_signal(&m_signal_cond);
|
}
|
|
|
private:
|
|
pthread_cond_t m_signal_cond;
|
pthread_mutex_t m_signal_cond_mutex;
|
|
};
|
|
class GlobalSignalWaitLock {
|
|
public:
|
// 仅支持一对一,#TODO多对一
|
static GlobalSignalWaitLock &getInstance() {
|
static GlobalSignalWaitLock globalSignalWaitLock;
|
return globalSignalWaitLock;
|
}
|
|
protected:
|
GlobalSignalWaitLock() : m_live(true) {}
|
|
virtual ~GlobalSignalWaitLock() {
|
m_slRwLock.wrlock();
|
m_signalLock.clear();
|
m_slRwLock.unlock();
|
|
}
|
|
private:
|
bool m_live;
|
RWLock m_slRwLock;
|
std::map<std::string, SignalLock> m_signalLock;
|
|
public:
|
bool waitSignal(std::string key) {
|
try {
|
m_slRwLock.rdlock();
|
if (m_signalLock.find(key) == m_signalLock.end()) {
|
m_slRwLock.r2wLock();
|
m_signalLock[key] = std::move(SignalLock());
|
m_slRwLock.w2rLock();
|
}
|
SignalLock &t_signalLock = m_signalLock[key];
|
m_slRwLock.unlock();
|
t_signalLock.wait();
|
} catch (std::exception ex) {
|
ERR(ex.what());
|
m_slRwLock.unlock();
|
return false;
|
}
|
return true;
|
}
|
|
bool emitSigal(std::string key) {
|
try {
|
m_slRwLock.rdlock();
|
if (m_signalLock.find(key) == m_signalLock.end()) {
|
m_slRwLock.r2wLock();
|
m_signalLock[key] = std::move(SignalLock());
|
m_slRwLock.w2rLock();
|
}
|
SignalLock &t_signalLock = m_signalLock[key];
|
m_slRwLock.unlock();
|
t_signalLock.emit();
|
} catch (std::exception ex) {
|
ERR(ex.what());
|
m_slRwLock.unlock();
|
return false;
|
}
|
return true;
|
|
}
|
};
|
|
|
#endif //GB28181SDK_GLOBALSIGNALWAITLOCK_H
|