From e07aa7e226d9b70dd913b4d639369e3952e61bab Mon Sep 17 00:00:00 2001 From: Won Chung Date: Tue, 6 Jun 2023 00:46:41 +0000 Subject: [PATCH] ui/display/manager: Do not use DisplaySnapshot* in callbacks DisplaySnapshot* may be no longer available when used in callbacks with different thread, so extract just necessary information to pass onto callbacks (cherry picked from commit b8f2d81b91933297fd595764da9d49627ffb796d) Bug: b/285010517 Test: Pass unit tests Change-Id: I08463eae9834440ac7f32ec74df4712c2a69ac8f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4575491 Reviewed-by: Xiyuan Xia Reviewed-by: Mitsuru Oshima Commit-Queue: Won Chung Cr-Original-Commit-Position: refs/heads/main@{#1152755} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4591742 Cr-Commit-Position: refs/branch-heads/5790@{#389} Cr-Branched-From: 1d71a337b1f6e707a13ae074dca1e2c34905eb9f-refs/heads/main@{#1148114} --- ui/display/manager/display_port_observer.cc | 25 +++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/ui/display/manager/display_port_observer.cc b/ui/display/manager/display_port_observer.cc index 87a11fdd95c25..7a81a94032f72 100644 --- a/ui/display/manager/display_port_observer.cc +++ b/ui/display/manager/display_port_observer.cc @@ -23,14 +23,17 @@ namespace { const LazyRE2 kTypecConnUeventPattern = {R"(TYPEC_PORT=port(\d+))"}; std::vector ParseDrmSysfsAndFindPort( - const DisplayConfigurator::DisplayStateList& display_states) { + const std::vector>& + base_connector_id_and_syspath) { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); std::vector port_nums; - for (auto* state : display_states) { - // Each DisplaySnapshot holds the `sys_path` of a DRM device (i.e. - // /sys/class/drm/cardX). - base::FileEnumerator enumerator(state->sys_path(), false, + // Each pair is from each DisplaySnapshot. + for (const auto& pair : base_connector_id_and_syspath) { + auto base_connector_id = pair.first; + const auto& sys_path = pair.second; + // `sys_path` of a DRM device, i.e. /sys/class/drm/cardX. + base::FileEnumerator enumerator(sys_path, false, base::FileEnumerator::DIRECTORIES); // Each directory in `sys_path` represents a connector, so we fetch each // connector's ID by reading the `/sys/class/drm/*/connector_id` file @@ -52,7 +55,7 @@ std::vector ParseDrmSysfsAndFindPort( << path.value(); continue; } - if (connector_id_int != state->base_connector_id()) { + if (connector_id_int != base_connector_id) { continue; } // A connector with a matching id is found at this point, so break the @@ -111,11 +114,19 @@ void DisplayPortObserver::OnDisplayModeChanged( } prev_base_connector_ids_ = base_connector_ids_; + // For each DisplaySnapshot, extract base_connector_id and sys_path. + std::vector> + base_connector_id_and_syspath; + for (auto* state : display_states) { + base_connector_id_and_syspath.push_back( + std::make_pair(state->base_connector_id(), state->sys_path())); + } + base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - base::BindOnce(&ParseDrmSysfsAndFindPort, display_states), + base::BindOnce(&ParseDrmSysfsAndFindPort, base_connector_id_and_syspath), base::BindOnce(&DisplayPortObserver::SetTypeCPortsUsingDisplays, weak_ptr_factory_.GetWeakPtr())); }