派生自 development/c++

pansen
2019-03-07 d3b7bbe7102cd089680a828f5d8f6402c8cf6342
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//
// 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