int32_t ObjCDesktopMediaList::UpdateSourceList(bool force_reload, bool get_thumbnail) {
if (force_reload) {
for (auto source : sources_) {
[objcMediaList_ mediaSourceRemoved:source.get()];
}
sources_.clear();
}
webrtc::DesktopCapturer::SourceList new_sources;
thread_->BlockingCall([this, &new_sources] {
capturer_->GetSourceList(&new_sources);
});
typedef std::set<DesktopCapturer::SourceId> SourceSet;
SourceSet new_source_set;
for (size_t i = 0; i < new_sources.size(); ++i) {
if (type_ == kScreen && new_sources[i].title.length() == 0) {
new_sources[i].title = std::string("Screen " + std::to_string(i + 1));
}
new_source_set.insert(new_sources[i].id);
}
// Iterate through the old sources to find the removed sources.
for (size_t i = 0; i < sources_.size(); ++i) {
if (new_source_set.find(sources_[i]->id()) == new_source_set.end()) {
[objcMediaList_ mediaSourceRemoved:(*(sources_.begin() + i)).get()];
sources_.erase(sources_.begin() + i);
--i;
}
}
// Iterate through the new sources to find the added sources.
if (new_sources.size() > sources_.size()) {
SourceSet old_source_set;
for (size_t i = 0; i < sources_.size(); ++i) {
old_source_set.insert(sources_[i]->id());
}
for (size_t i = 0; i < new_sources.size(); ++i) {
if (old_source_set.find(new_sources[i].id) == old_source_set.end()) {
MediaSource *source = new MediaSource(this, new_sources[i], type_);
sources_.insert(sources_.begin() + i, std::shared_ptr<MediaSource>(source));
[objcMediaList_ mediaSourceAdded:source];
GetThumbnail(source, true);
}
}
}
RTC_DCHECK_EQ(new_sources.size(), sources_.size());
// Find the moved/changed sources.
size_t pos = 0;
while (pos < sources_.size()) {
if (!(sources_[pos]->id() == new_sources[pos].id)) {
// Find the source that should be moved to |pos|, starting from |pos + 1|
// of |sources_|, because entries before |pos| should have been sorted.
size_t old_pos = pos + 1;
for (; old_pos < sources_.size(); ++old_pos) {
if (sources_[old_pos]->id() == new_sources[pos].id) break;
}
RTC_DCHECK(sources_[old_pos]->id() == new_sources[pos].id);
// Move the source from |old_pos| to |pos|.
auto temp = sources_[old_pos];
sources_.erase(sources_.begin() + old_pos);
sources_.insert(sources_.begin() + pos, temp);
//[objcMediaList_ mediaSourceMoved:old_pos newIndex:pos];
}
if (sources_[pos]->source.title != new_sources[pos].title) {
sources_[pos]->source.title = new_sources[pos].title;
[objcMediaList_ mediaSourceNameChanged:sources_[pos].get()];
}
++pos;
}
if (get_thumbnail) {
for (auto source : sources_) {
GetThumbnail(source.get(), true);
}
}
return sources_.size();
}
This method crashes when called simultaneously by multiple threads with force_reload = true. I suggest modifying the implementation to use a mutex lock to protect shared resources and ensure safe access in a multi-threaded environment. Here is the suggested modification:
This method crashes when called simultaneously by multiple threads with force_reload = true. I suggest modifying the implementation to use a mutex lock to protect shared resources and ensure safe access in a multi-threaded environment. Here is the suggested modification: