mirror of
https://github.com/zed-industries/zed.git
synced 2026-08-25 00:45:27 +00:00
Support Restart Manager shutdown on Windows
This commit is contained in:
parent
d9ad6aff67
commit
2cddfdbf20
3 changed files with 78 additions and 1 deletions
|
|
@ -182,6 +182,7 @@ pub struct CrashServer {
|
|||
active_gpu: Mutex<Option<system_specs::GpuSpecs>>,
|
||||
user_info: Mutex<Option<UserInfo>>,
|
||||
abort_message_location: Mutex<Option<AbortMessageLocation>>,
|
||||
shutdown: Arc<AtomicBool>,
|
||||
has_connection: Arc<AtomicBool>,
|
||||
logs_dir: PathBuf,
|
||||
}
|
||||
|
|
@ -255,6 +256,11 @@ pub fn set_user_info(crash_client: &Arc<Client>, info: UserInfo) {
|
|||
send_crash_server_message(crash_client, CrashServerMessage::UserInfo(info));
|
||||
}
|
||||
|
||||
/// Requests an orderly exit from the crash-handler sidecar.
|
||||
pub fn shutdown_crash_handler(crash_client: &Arc<Client>) {
|
||||
send_crash_server_message(crash_client, CrashServerMessage::Shutdown);
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
enum CrashServerMessage {
|
||||
Init(InitCrashHandler),
|
||||
|
|
@ -262,6 +268,7 @@ enum CrashServerMessage {
|
|||
GPUInfo(GpuSpecs),
|
||||
UserInfo(UserInfo),
|
||||
AbortMessageLocation(AbortMessageLocation),
|
||||
Shutdown,
|
||||
}
|
||||
|
||||
/// glibc records the diagnostic it prints just before aborting (malloc integrity
|
||||
|
|
@ -464,6 +471,9 @@ impl minidumper::ServerHandler for CrashServer {
|
|||
CrashServerMessage::AbortMessageLocation(location) => {
|
||||
self.abort_message_location.lock().replace(location);
|
||||
}
|
||||
CrashServerMessage::Shutdown => {
|
||||
self.shutdown.store(true, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -668,6 +678,7 @@ pub fn crash_server(socket: &Path, logs_dir: PathBuf) {
|
|||
panic_info: Mutex::default(),
|
||||
user_info: Mutex::default(),
|
||||
abort_message_location: Mutex::default(),
|
||||
shutdown: shutdown.clone(),
|
||||
has_connection,
|
||||
active_gpu: Mutex::default(),
|
||||
logs_dir,
|
||||
|
|
@ -682,6 +693,44 @@ pub fn crash_server(socket: &Path, logs_dir: PathBuf) {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn shutdown_stops_crash_server() {
|
||||
let unique = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.expect("system clock is before the Unix epoch")
|
||||
.as_nanos();
|
||||
let socket = PathBuf::from(format!(
|
||||
"crashes-shutdown-test-{}-{unique}",
|
||||
std::process::id()
|
||||
));
|
||||
let logs_dir = std::env::temp_dir();
|
||||
let (server_stopped_tx, server_stopped_rx) = std::sync::mpsc::channel();
|
||||
let server_socket = socket.clone();
|
||||
std::thread::spawn(move || {
|
||||
crash_server(&server_socket, logs_dir);
|
||||
server_stopped_tx
|
||||
.send(())
|
||||
.expect("test receiver should remain connected");
|
||||
});
|
||||
|
||||
let client = Arc::new(
|
||||
(0..100)
|
||||
.find_map(|_| {
|
||||
let client = Client::with_name(SocketName::Path(&socket)).ok();
|
||||
if client.is_none() {
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
client
|
||||
})
|
||||
.expect("crash server did not start"),
|
||||
);
|
||||
|
||||
shutdown_crash_handler(&client);
|
||||
server_stopped_rx
|
||||
.recv_timeout(Duration::from_secs(2))
|
||||
.expect("crash server did not stop");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn abort_message_read_len_requires_page_rounded_total() {
|
||||
assert_eq!(abort_message_read_len(0), None);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ pub(crate) const WM_GPUI_FORCE_UPDATE_WINDOW: u32 = WM_USER + 5;
|
|||
pub(crate) const WM_GPUI_KEYBOARD_LAYOUT_CHANGED: u32 = WM_USER + 6;
|
||||
pub(crate) const WM_GPUI_GPU_DEVICE_LOST: u32 = WM_USER + 7;
|
||||
pub(crate) const WM_GPUI_KEYDOWN: u32 = WM_USER + 8;
|
||||
pub(crate) const WM_GPUI_END_SESSION: u32 = WM_USER + 9;
|
||||
|
||||
const SIZE_MOVE_LOOP_TIMER_ID: usize = 1;
|
||||
|
||||
|
|
@ -108,6 +109,8 @@ impl WindowsWindowInner {
|
|||
WM_PAINT => self.handle_paint_msg(handle),
|
||||
WM_CLOSE => self.handle_close_msg(),
|
||||
WM_DESTROY => self.handle_destroy_msg(handle),
|
||||
WM_QUERYENDSESSION => Some(1),
|
||||
WM_ENDSESSION => self.handle_end_session_msg(wparam),
|
||||
WM_MOUSEMOVE => self.handle_mouse_move_msg(handle, lparam, wparam),
|
||||
WM_MOUSELEAVE | WM_NCMOUSELEAVE => self.handle_mouse_leave_msg(),
|
||||
WM_NCMOUSEMOVE => self.handle_nc_mouse_move_msg(handle, lparam),
|
||||
|
|
@ -170,6 +173,20 @@ impl WindowsWindowInner {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_end_session_msg(&self, wparam: WPARAM) -> Option<isize> {
|
||||
if wparam.0 != 0 {
|
||||
unsafe {
|
||||
SendMessageW(
|
||||
self.platform_window_handle,
|
||||
WM_GPUI_END_SESSION,
|
||||
Some(WPARAM(self.validation_number)),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
Some(0)
|
||||
}
|
||||
|
||||
fn handle_move_msg(&self, handle: HWND, lparam: LPARAM) -> Option<isize> {
|
||||
let origin = logical_point(
|
||||
lparam.signed_loword() as f32,
|
||||
|
|
|
|||
|
|
@ -997,7 +997,8 @@ impl WindowsPlatformInner {
|
|||
| WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD
|
||||
| WM_GPUI_DOCK_MENU_ACTION
|
||||
| WM_GPUI_KEYBOARD_LAYOUT_CHANGED
|
||||
| WM_GPUI_GPU_DEVICE_LOST => self.handle_gpui_events(msg, wparam, lparam),
|
||||
| WM_GPUI_GPU_DEVICE_LOST
|
||||
| WM_GPUI_END_SESSION => self.handle_gpui_events(msg, wparam, lparam),
|
||||
WM_POWERBROADCAST => self.handle_power_broadcast(wparam),
|
||||
_ => None,
|
||||
};
|
||||
|
|
@ -1022,10 +1023,20 @@ impl WindowsPlatformInner {
|
|||
WM_GPUI_DOCK_MENU_ACTION => self.handle_dock_action_event(lparam.0 as _),
|
||||
WM_GPUI_KEYBOARD_LAYOUT_CHANGED => self.handle_keyboard_layout_change(),
|
||||
WM_GPUI_GPU_DEVICE_LOST => self.handle_device_lost(lparam),
|
||||
WM_GPUI_END_SESSION => self.handle_end_session(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_end_session(&self) -> Option<isize> {
|
||||
let callback = self.state.callbacks.quit.take();
|
||||
if let Some(mut callback) = callback {
|
||||
callback();
|
||||
}
|
||||
unsafe { PostQuitMessage(0) };
|
||||
Some(0)
|
||||
}
|
||||
|
||||
fn close_one_window(&self, target_window: HWND) -> bool {
|
||||
let Some(all_windows) = self.raw_window_handles.upgrade() else {
|
||||
log::error!("Failed to upgrade raw window handles");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue