Commit 33dbdb00 authored by kylechar's avatar kylechar Committed by Commit Bot

Fix GpuChannel destruction order

GpuChannelManager::RemoveChannel() removes the map entry for a
GpuChannel and destroys the GpuChannel at the same time. This is
problematic because the GpuChannel destructor can trigger context loss
which leads back to GpuChannelManager::LoseAllContexts(). That will
iterate over |gpu_channels_| in the middle of removing an element.

Fix by removing the map entry first and then deleting the GpuChannel
object. This is already done in DestroyAllChannels() for the same
reason.

Bug: 1067642
Change-Id: I5ccba54151686726b24af97a06c0bd7bf7f06d5a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2152767Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: kylechar <kylechar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759729}
parent 697b8f4a
......@@ -358,8 +358,18 @@ gles2::ProgramCache* GpuChannelManager::program_cache() {
void GpuChannelManager::RemoveChannel(int client_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = gpu_channels_.find(client_id);
if (it == gpu_channels_.end())
return;
delegate_->DidDestroyChannel(client_id);
gpu_channels_.erase(client_id);
// Erase the |gpu_channels_| entry before destroying the GpuChannel object to
// avoid reentrancy problems from the GpuChannel destructor.
std::unique_ptr<GpuChannel> channel = std::move(it->second);
gpu_channels_.erase(it);
channel.reset();
if (gpu_channels_.empty()) {
delegate_->DidDestroyAllChannels();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment