70 lines
2.5 KiB
Diff
70 lines
2.5 KiB
Diff
--- a/src/main.rs
|
|
+++ b/src/main.rs
|
|
@@ -24,6 +24,7 @@ use redox_driver_sys::pcid_client::PcidClient;
|
|
use redox_driver_sys::quirks::PciQuirkFlags;
|
|
use redox_scheme::{SignalBehavior, Socket};
|
|
+use syscall04::error::EBADF;
|
|
|
|
use crate::driver::{DriverError, DriverEvent, GpuDriver, Result};
|
|
use crate::drivers::DriverRegistry;
|
|
@@ -71,11 +72,6 @@ fn run() -> Result<()> {
|
|
info.location
|
|
);
|
|
|
|
- let socket = Socket::create("drm")
|
|
- .map_err(|e| DriverError::Initialization(format!("failed to register drm scheme: {e}")))?;
|
|
- info!("redox-drm: registered scheme:drm");
|
|
-
|
|
let (event_tx, event_rx) = mpsc::sync_channel::<DriverEvent>(8);
|
|
|
|
let irq_driver: Arc<dyn GpuDriver> = driver.clone();
|
|
@@ -108,6 +104,15 @@ fn run() -> Result<()> {
|
|
}
|
|
});
|
|
|
|
+ // redox-scheme opens the scheme fd with O_CLOEXEC. On Redox, thread startup can
|
|
+ // invalidate a close-on-exec fd opened before the thread workers exist, which
|
|
+ // showed up as an immediate EBADF from next_request() during QEMU greeter boot.
|
|
+ // Register scheme:drm only after the worker threads are running so the listening
|
|
+ // fd remains stable for compositor clients.
|
|
+ let socket = create_drm_socket()?;
|
|
+ info!("redox-drm: registered scheme:drm");
|
|
+
|
|
loop {
|
|
let request = match socket.next_request(SignalBehavior::Restart) {
|
|
Ok(Some(request)) => request,
|
|
@@ -118,6 +123,10 @@ fn run() -> Result<()> {
|
|
break;
|
|
}
|
|
Err(e) => {
|
|
+ if e.errno == EBADF {
|
|
+ info!("redox-drm: scheme fd closed, exiting");
|
|
+ break;
|
|
+ }
|
|
error!("redox-drm: failed to receive scheme request: {}", e);
|
|
continue;
|
|
}
|
|
@@ -145,11 +154,22 @@ fn run() -> Result<()> {
|
|
};
|
|
|
|
if let Err(e) = socket.write_response(response, SignalBehavior::Restart) {
|
|
+ if e.errno == EBADF {
|
|
+ info!("redox-drm: scheme fd closed while writing response, exiting");
|
|
+ break;
|
|
+ }
|
|
error!("redox-drm: failed to write scheme response: {}", e);
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
+fn create_drm_socket() -> Result<Socket> {
|
|
+ Socket::create("drm")
|
|
+ .map_err(|e| DriverError::Initialization(format!("failed to register drm scheme: {e}")))
|
|
+}
|
|
+
|
|
fn select_gpu_from_args() -> Result<PciDeviceInfo> {
|
|
let mut args = env::args().skip(1);
|
|
let parsed = match (args.next(), args.next(), args.next()) {
|