Commit 45c5f1ec by xiongziliang

避免死锁

parent e1929314
ZLToolKit @ 58a74f8c
Subproject commit 69227690e1b6e63f43969aafda0263e05f41a14a Subproject commit 58a74f8c5ab802a0dd9fdcdcc0fe4c5a3d841964
...@@ -119,8 +119,15 @@ bool MediaSource::isRecording(Recorder::type type){ ...@@ -119,8 +119,15 @@ bool MediaSource::isRecording(Recorder::type type){
} }
void MediaSource::for_each_media(const function<void(const MediaSource::Ptr &src)> &cb) { void MediaSource::for_each_media(const function<void(const MediaSource::Ptr &src)> &cb) {
lock_guard<recursive_mutex> lock(g_mtxMediaSrc); decltype(g_mapMediaSrc) copy;
for (auto &pr0 : g_mapMediaSrc) { {
//拷贝g_mapMediaSrc后再遍历,考虑到是高频使用的全局单例锁,并且在上锁时会执行回调代码
//很容易导致多个锁交叉死锁的情况,而且该函数使用频率不高,拷贝开销相对来说是可以接受的
lock_guard<recursive_mutex> lock(g_mtxMediaSrc);
copy = g_mapMediaSrc;
}
for (auto &pr0 : copy) {
for (auto &pr1 : pr0.second) { for (auto &pr1 : pr0.second) {
for (auto &pr2 : pr1.second) { for (auto &pr2 : pr1.second) {
for (auto &pr3 : pr2.second) { for (auto &pr3 : pr2.second) {
......
...@@ -192,13 +192,17 @@ public: ...@@ -192,13 +192,17 @@ public:
virtual ~FrameDispatcher(){} virtual ~FrameDispatcher(){}
void addDelegate(const FrameWriterInterface::Ptr &delegate){ void addDelegate(const FrameWriterInterface::Ptr &delegate){
//_delegates_write可能多线程同时操作
lock_guard<mutex> lck(_mtx); lock_guard<mutex> lck(_mtx);
_delegateMap.emplace(delegate.get(),delegate); _delegates_write.emplace(delegate.get(),delegate);
_need_update = true;
} }
void delDelegate(void *ptr){ void delDelegate(void *ptr){
//_delegates_write可能多线程同时操作
lock_guard<mutex> lck(_mtx); lock_guard<mutex> lck(_mtx);
_delegateMap.erase(ptr); _delegates_write.erase(ptr);
_need_update = true;
} }
/** /**
...@@ -206,14 +210,23 @@ public: ...@@ -206,14 +210,23 @@ public:
* @param frame 帧 * @param frame 帧
*/ */
void inputFrame(const Frame::Ptr &frame) override{ void inputFrame(const Frame::Ptr &frame) override{
lock_guard<mutex> lck(_mtx); //_delegates_read能确保是单线程操作的
for(auto &pr : _delegateMap){ for(auto &pr : _delegates_read){
pr.second->inputFrame(frame); pr.second->inputFrame(frame);
} }
if(_need_update){
//发现代理列表发生变化了,这里同步一次
lock_guard<mutex> lck(_mtx);
_delegates_read = _delegates_write;
_need_update = false;
}
} }
private: private:
mutex _mtx; mutex _mtx;
map<void *,FrameWriterInterface::Ptr> _delegateMap; map<void *,FrameWriterInterface::Ptr> _delegates_read;
map<void *,FrameWriterInterface::Ptr> _delegates_write;
bool _need_update = false;
}; };
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论