Fix local task dropped on the wrong thread (#28290)
Release Notes: - Fixed a panic during shutdown of the remote server
This commit is contained in:
@@ -106,7 +106,17 @@ impl PlatformDispatcher for LinuxDispatcher {
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: Runnable) {
|
||||
self.main_sender.send(runnable).ok();
|
||||
self.main_sender.send(runnable).unwrap_or_else(|runnable| {
|
||||
// NOTE: Runnable may wrap a Future that is !Send.
|
||||
//
|
||||
// This is usually safe because we only poll it on the main thread.
|
||||
// However if the send fails, we know that:
|
||||
// 1. main_receiver has been dropped (which implies the app is shutting down)
|
||||
// 2. we are on a background thread.
|
||||
// It is not safe to drop something !Send on the wrong thread, and
|
||||
// the app will exit soon anyway, so we must forget the runnable.
|
||||
std::mem::forget(runnable);
|
||||
});
|
||||
}
|
||||
|
||||
fn dispatch_after(&self, duration: Duration, runnable: Runnable) {
|
||||
|
||||
@@ -3,7 +3,6 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::Context as _;
|
||||
use async_task::Runnable;
|
||||
use flume::Sender;
|
||||
use parking::Parker;
|
||||
@@ -95,14 +94,8 @@ impl PlatformDispatcher for WindowsDispatcher {
|
||||
}
|
||||
|
||||
fn dispatch_on_main_thread(&self, runnable: Runnable) {
|
||||
if self
|
||||
.main_sender
|
||||
.send(runnable)
|
||||
.context("Dispatch on main thread failed")
|
||||
.log_err()
|
||||
.is_some()
|
||||
{
|
||||
unsafe {
|
||||
match self.main_sender.send(runnable) {
|
||||
Ok(_) => unsafe {
|
||||
PostThreadMessageW(
|
||||
self.main_thread_id_win32,
|
||||
WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD,
|
||||
@@ -110,6 +103,17 @@ impl PlatformDispatcher for WindowsDispatcher {
|
||||
LPARAM(0),
|
||||
)
|
||||
.log_err();
|
||||
},
|
||||
Err(runnable) => {
|
||||
// NOTE: Runnable may wrap a Future that is !Send.
|
||||
//
|
||||
// This is usually safe because we only poll it on the main thread.
|
||||
// However if the send fails, we know that:
|
||||
// 1. main_receiver has been dropped (which implies the app is shutting down)
|
||||
// 2. we are on a background thread.
|
||||
// It is not safe to drop something !Send on the wrong thread, and
|
||||
// the app will exit soon anyway, so we must forget the runnable.
|
||||
std::mem::forget(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user