diff --git a/media/mojo/services/oop_video_decoder_factory_process_service.cc b/media/mojo/services/oop_video_decoder_factory_process_service.cc index 0000000000000..0000000000000 100644 --- a/media/mojo/services/oop_video_decoder_factory_process_service.cc +++ b/media/mojo/services/oop_video_decoder_factory_process_service.cc @@ -22,7 +22,12 @@ OOPVideoDecoderFactoryProcessService::OOPVideoDecoderFactoryProcessService( OOPVideoDecoderFactoryProcessService::~OOPVideoDecoderFactoryProcessService() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (shared_image_interface_ && !shared_image_interface_->IsLost()) { + // Unconditionally remove ourselves from the observer list. The previous + // `!IsLost()` guard introduced a TOCTOU race: the IO thread can publish + // `is_connected_ = false` before taking `channel_obs_lock_`, causing this + // destructor to skip removal while a raw `this` is still pending iteration + // in ConnectionTracker::NotifyGpuChannelLost(). + if (shared_image_interface_) { shared_image_interface_->RemoveGpuChannelLostObserver(this); } }