mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 23:38:06 +08:00
Review
This commit is contained in:
@@ -8,13 +8,13 @@ use crate::frames::surface::FrameSurface;
|
||||
use crate::remote::HostConfig;
|
||||
use crate::remote::messages::EventMessage;
|
||||
|
||||
struct ParentProcess(HANDLE);
|
||||
struct MainProcess(HANDLE);
|
||||
|
||||
// SAFETY: process handles may be used and closed from any thread.
|
||||
unsafe impl Send for ParentProcess {}
|
||||
unsafe impl Sync for ParentProcess {}
|
||||
unsafe impl Send for MainProcess {}
|
||||
unsafe impl Sync for MainProcess {}
|
||||
|
||||
impl ParentProcess {
|
||||
impl MainProcess {
|
||||
fn open(pid: u32) -> windows::core::Result<Self> {
|
||||
// SAFETY: plain OpenProcess call; on success the handle is ours to close.
|
||||
unsafe { OpenProcess(PROCESS_DUP_HANDLE, false, pid).map(Self) }
|
||||
@@ -27,7 +27,7 @@ impl ParentProcess {
|
||||
Ok(target.0 as u64)
|
||||
}
|
||||
|
||||
fn close_in_parent(&self, handle: u64) {
|
||||
fn close_in_main(&self, handle: u64) {
|
||||
let mut reclaimed = HANDLE::default();
|
||||
// SAFETY: `handle` came from `duplicate_into` and is valid.
|
||||
unsafe {
|
||||
@@ -41,7 +41,7 @@ impl ParentProcess {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ParentProcess {
|
||||
impl Drop for MainProcess {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: we own the process handle.
|
||||
unsafe {
|
||||
@@ -51,14 +51,14 @@ impl Drop for ParentProcess {
|
||||
}
|
||||
|
||||
pub(crate) struct PlaneSender {
|
||||
parent: Arc<ParentProcess>,
|
||||
main: Arc<MainProcess>,
|
||||
events: Arc<Mutex<IpcSender<EventMessage>>>,
|
||||
}
|
||||
|
||||
impl PlaneSender {
|
||||
pub(crate) fn from_config(config: &HostConfig, events: Arc<Mutex<IpcSender<EventMessage>>>) -> Option<Self> {
|
||||
match ParentProcess::open(config.main_pid) {
|
||||
Ok(parent) => Some(Self { parent: Arc::new(parent), events }),
|
||||
match MainProcess::open(config.main_pid) {
|
||||
Ok(main) => Some(Self { main: Arc::new(main), events }),
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to open the main process for handle duplication, falling back to software frames: {e}");
|
||||
None
|
||||
@@ -67,7 +67,7 @@ impl PlaneSender {
|
||||
}
|
||||
|
||||
pub(crate) fn stage(&self, info: &cef::AcceleratedPaintInfo) -> Option<StagedFrame> {
|
||||
let handle = match self.parent.duplicate_into(HANDLE(info.shared_texture_handle)) {
|
||||
let handle = match self.main.duplicate_into(HANDLE(info.shared_texture_handle)) {
|
||||
Ok(handle) => handle,
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to duplicate the shared texture handle into the main process: {e}");
|
||||
@@ -75,7 +75,7 @@ impl PlaneSender {
|
||||
}
|
||||
};
|
||||
Some(StagedFrame {
|
||||
handle: HandleInParent { handle, parent: self.parent.clone() },
|
||||
handle: HandleInMain { handle, main: self.main.clone() },
|
||||
width: info.extra.coded_size.width as u32,
|
||||
height: info.extra.coded_size.height as u32,
|
||||
format: *info.format.as_ref() as u32,
|
||||
@@ -103,20 +103,20 @@ impl PlaneSender {
|
||||
}
|
||||
|
||||
pub(crate) struct StagedFrame {
|
||||
handle: HandleInParent,
|
||||
handle: HandleInMain,
|
||||
width: u32,
|
||||
height: u32,
|
||||
format: u32,
|
||||
}
|
||||
|
||||
struct HandleInParent {
|
||||
struct HandleInMain {
|
||||
handle: u64,
|
||||
parent: Arc<ParentProcess>,
|
||||
main: Arc<MainProcess>,
|
||||
}
|
||||
|
||||
impl Drop for HandleInParent {
|
||||
impl Drop for HandleInMain {
|
||||
fn drop(&mut self) {
|
||||
self.parent.close_in_parent(self.handle);
|
||||
self.main.close_in_main(self.handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@ use std::process::Command;
|
||||
use crate::frames::plane;
|
||||
|
||||
pub(crate) fn setup_command(command: &mut Command, #[cfg(feature = "accelerated_paint")] host_frame_fd: Option<std::os::fd::RawFd>) {
|
||||
let parent_pid = std::process::id() as libc::pid_t;
|
||||
let main_pid = std::process::id() as libc::pid_t;
|
||||
// SAFETY: the closure runs in the forked child before exec and only makes async-signal-safe calls
|
||||
unsafe {
|
||||
command.pre_exec(move || {
|
||||
// Tie the host's lifetime to the parent process
|
||||
// Tie the host's lifetime to the main process
|
||||
if libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL) != 0 {
|
||||
return Err(std::io::Error::last_os_error());
|
||||
}
|
||||
if libc::getppid() != parent_pid {
|
||||
if libc::getppid() != main_pid {
|
||||
return Err(std::io::Error::other("main process died before PDEATHSIG was set"));
|
||||
}
|
||||
|
||||
|
||||
@@ -51,13 +51,13 @@ pub(crate) fn spawn_parent_watchdog(main_pid: u32) {
|
||||
loop {
|
||||
// SAFETY: getppid is always safe to call.
|
||||
if unsafe { libc::getppid() } as u32 != main_pid {
|
||||
tracing::warn!("Main process is gone, exiting CEF host");
|
||||
tracing::warn!("Parent process is gone, exiting...");
|
||||
std::process::exit(0);
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(500));
|
||||
}
|
||||
});
|
||||
if let Err(e) = result {
|
||||
tracing::error!("Failed to spawn the parent watchdog: {e}");
|
||||
tracing::error!("Failed to spawn parent watchdog: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user