mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 10:40:05 +08:00
避免死锁
This commit is contained in:
parent
e192931429
commit
45c5f1ec4c
@ -1 +1 @@
|
|||||||
Subproject commit 69227690e1b6e63f43969aafda0263e05f41a14a
|
Subproject commit 58a74f8c5ab802a0dd9fdcdcc0fe4c5a3d841964
|
@ -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:
|
|||||||
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:
|
|||||||
* @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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user