Commit f1b9bf57 authored by Tom Anderson's avatar Tom Anderson Committed by Commit Bot

Fix crash in ui::XShmImagePool::DispatchShmCompletionEvent

The issue can be reproduced by creating and closing windows really
fast (like when you're using a tiling WM and dragging tabs and it
sort of bugs out).  In that case the following was getting hit:
  CHECK(!swap_closures_.empty());

The solution is to do loop through |swap_closures_| and remove only
the matching element.

BUG=1057943
R=nickdiego

Change-Id: Ib55f6326df6c444adf1bdc6f710785a05cb0d619
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2090354
Commit-Queue: Nick Yamane <nickdiego@igalia.com>
Reviewed-by: default avatarNick Yamane <nickdiego@igalia.com>
Auto-Submit: Thomas Anderson <thomasanderson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747658}
parent 4cba05d3
...@@ -270,7 +270,7 @@ void XShmImagePool::SwapBuffers( ...@@ -270,7 +270,7 @@ void XShmImagePool::SwapBuffers(
base::OnceCallback<void(const gfx::Size&)> callback) { base::OnceCallback<void(const gfx::Size&)> callback) {
DCHECK(host_task_runner_->RunsTasksInCurrentSequence()); DCHECK(host_task_runner_->RunsTasksInCurrentSequence());
swap_closures_.emplace(); swap_closures_.emplace_back();
SwapClosure& swap_closure = swap_closures_.back(); SwapClosure& swap_closure = swap_closures_.back();
swap_closure.closure = base::BindOnce(std::move(callback), pixel_size_); swap_closure.closure = base::BindOnce(std::move(callback), pixel_size_);
swap_closure.shmseg = frame_states_[current_frame_index_].shminfo_.shmseg; swap_closure.shmseg = frame_states_[current_frame_index_].shminfo_.shmseg;
...@@ -300,16 +300,16 @@ XShmImagePool::~XShmImagePool() { ...@@ -300,16 +300,16 @@ XShmImagePool::~XShmImagePool() {
} }
void XShmImagePool::DispatchShmCompletionEvent(XShmCompletionEvent event) { void XShmImagePool::DispatchShmCompletionEvent(XShmCompletionEvent event) {
// DCHECKs replaced with CHECKs here for https://crbug.com/1057943 DCHECK(host_task_runner_->RunsTasksInCurrentSequence());
CHECK(host_task_runner_->RunsTasksInCurrentSequence()); DCHECK_EQ(event.offset, 0UL);
CHECK(!swap_closures_.empty());
SwapClosure& swap_ack = swap_closures_.front();
CHECK_EQ(event.shmseg, swap_ack.shmseg);
CHECK_EQ(event.offset, 0UL);
std::move(swap_ack.closure).Run(); for (auto it = swap_closures_.begin(); it != swap_closures_.end(); ++it) {
swap_closures_.pop(); if (event.shmseg == it->shmseg) {
std::move(it->closure).Run();
swap_closures_.erase(it);
return;
}
}
} }
bool XShmImagePool::CanDispatchXEvent(XEvent* xev) { bool XShmImagePool::CanDispatchXEvent(XEvent* xev) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define UI_BASE_X_X11_SHM_IMAGE_POOL_H_ #define UI_BASE_X_X11_SHM_IMAGE_POOL_H_
#include <cstring> #include <cstring>
#include <queue> #include <list>
#include <vector> #include <vector>
#include "base/callback_forward.h" #include "base/callback_forward.h"
...@@ -115,7 +115,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XShmImagePool ...@@ -115,7 +115,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XShmImagePool
std::size_t frame_bytes_ = 0; std::size_t frame_bytes_ = 0;
std::vector<FrameState> frame_states_; std::vector<FrameState> frame_states_;
std::size_t current_frame_index_ = 0; std::size_t current_frame_index_ = 0;
std::queue<SwapClosure> swap_closures_; std::list<SwapClosure> swap_closures_;
DISALLOW_COPY_AND_ASSIGN(XShmImagePool); DISALLOW_COPY_AND_ASSIGN(XShmImagePool);
}; };
......
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