diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit index 69227690..58a74f8c 160000 --- a/3rdpart/ZLToolKit +++ b/3rdpart/ZLToolKit @@ -1 +1 @@ -Subproject commit 69227690e1b6e63f43969aafda0263e05f41a14a +Subproject commit 58a74f8c5ab802a0dd9fdcdcc0fe4c5a3d841964 diff --git a/src/Common/MediaSource.cpp b/src/Common/MediaSource.cpp index f20a2a2c..aa30ffbc 100644 --- a/src/Common/MediaSource.cpp +++ b/src/Common/MediaSource.cpp @@ -119,8 +119,15 @@ bool MediaSource::isRecording(Recorder::type type){ } void MediaSource::for_each_media(const function &cb) { - lock_guard lock(g_mtxMediaSrc); - for (auto &pr0 : g_mapMediaSrc) { + decltype(g_mapMediaSrc) copy; + { + //拷贝g_mapMediaSrc后再遍历,考虑到是高频使用的全局单例锁,并且在上锁时会执行回调代码 + //很容易导致多个锁交叉死锁的情况,而且该函数使用频率不高,拷贝开销相对来说是可以接受的 + lock_guard lock(g_mtxMediaSrc); + copy = g_mapMediaSrc; + } + + for (auto &pr0 : copy) { for (auto &pr1 : pr0.second) { for (auto &pr2 : pr1.second) { for (auto &pr3 : pr2.second) { diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index 0e297f28..b58c0049 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -192,13 +192,17 @@ public: virtual ~FrameDispatcher(){} void addDelegate(const FrameWriterInterface::Ptr &delegate){ + //_delegates_write可能多线程同时操作 lock_guard lck(_mtx); - _delegateMap.emplace(delegate.get(),delegate); + _delegates_write.emplace(delegate.get(),delegate); + _need_update = true; } void delDelegate(void *ptr){ + //_delegates_write可能多线程同时操作 lock_guard lck(_mtx); - _delegateMap.erase(ptr); + _delegates_write.erase(ptr); + _need_update = true; } /** @@ -206,14 +210,23 @@ public: * @param frame 帧 */ void inputFrame(const Frame::Ptr &frame) override{ - lock_guard lck(_mtx); - for(auto &pr : _delegateMap){ + //_delegates_read能确保是单线程操作的 + for(auto &pr : _delegates_read){ pr.second->inputFrame(frame); } + + if(_need_update){ + //发现代理列表发生变化了,这里同步一次 + lock_guard lck(_mtx); + _delegates_read = _delegates_write; + _need_update = false; + } } private: mutex _mtx; - map _delegateMap; + map _delegates_read; + map _delegates_write; + bool _need_update = false; }; /**