// // Created by pans on 19-1-13. // #ifndef GB28181SDK_GLOBALSIGNALWAITLOCK_H #define GB28181SDK_GLOBALSIGNALWAITLOCK_H #include #include #include //#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 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