From 4a9c3e5bbc32e7c2bdcaf62b2e82f1d128bf1e5c Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Sun, 4 May 2025 09:37:31 -0600 Subject: [PATCH] Prevent dropping a device while a control transfer is pending --- src/platform/linux_usbfs/device.rs | 14 ++++++++------ src/platform/macos_iokit/device.rs | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/platform/linux_usbfs/device.rs b/src/platform/linux_usbfs/device.rs index cacf954..488f537 100644 --- a/src/platform/linux_usbfs/device.rs +++ b/src/platform/linux_usbfs/device.rs @@ -323,24 +323,26 @@ impl LinuxDevice { } pub fn control_in( - &self, + self: Arc, data: ControlIn, timeout: Duration, ) -> impl MaybeFuture, TransferError>> { let t = TransferData::new_control_in(data); - TransferFuture::new(t, |t| self.submit_timeout(t, timeout)).map(|t| { + TransferFuture::new(t, |t| self.submit_timeout(t, timeout)).map(move |t| { + drop(self); // ensure device stays alive t.status()?; Ok(t.control_in_data().to_owned()) }) } pub fn control_out( - &self, + self: Arc, data: ControlOut, timeout: Duration, ) -> impl MaybeFuture> { let t = TransferData::new_control_out(data); - TransferFuture::new(t, |t| self.submit_timeout(t, timeout)).map(|t| { + TransferFuture::new(t, |t| self.submit_timeout(t, timeout)).map(move |t| { + drop(self); // ensure device stays alive t.status()?; Ok(()) }) @@ -570,7 +572,7 @@ impl LinuxInterface { data: ControlIn, timeout: Duration, ) -> impl MaybeFuture, TransferError>> { - self.device.control_in(data, timeout) + self.device.clone().control_in(data, timeout) } pub fn control_out( @@ -578,7 +580,7 @@ impl LinuxInterface { data: ControlOut, timeout: Duration, ) -> impl MaybeFuture> { - self.device.control_out(data, timeout) + self.device.clone().control_out(data, timeout) } pub fn get_alt_setting(&self) -> u8 { diff --git a/src/platform/macos_iokit/device.rs b/src/platform/macos_iokit/device.rs index 264b699..b1e52a7 100644 --- a/src/platform/macos_iokit/device.rs +++ b/src/platform/macos_iokit/device.rs @@ -222,7 +222,7 @@ impl MacDevice { } pub fn control_in( - self: &Arc, + self: Arc, data: ControlIn, timeout: Duration, ) -> impl MaybeFuture, TransferError>> { @@ -244,7 +244,8 @@ impl MacDevice { noDataTimeout: timeout, }; - TransferFuture::new(t, |t| self.submit_control(Direction::In, t, req)).map(|t| { + TransferFuture::new(t, |t| self.submit_control(Direction::In, t, req)).map(move |t| { + drop(self); // ensure device stays alive t.status()?; let t = ManuallyDrop::new(t); Ok(unsafe { Vec::from_raw_parts(t.buf, t.actual_len as usize, t.capacity as usize) }) @@ -252,7 +253,7 @@ impl MacDevice { } pub fn control_out( - self: &Arc, + self: Arc, data: ControlOut, timeout: Duration, ) -> impl MaybeFuture> { @@ -273,7 +274,8 @@ impl MacDevice { noDataTimeout: timeout, }; - TransferFuture::new(t, |t| self.submit_control(Direction::Out, t, req)).map(|t| { + TransferFuture::new(t, |t| self.submit_control(Direction::Out, t, req)).map(move |t| { + drop(self); // ensure device stays alive t.status()?; Ok(()) }) @@ -382,7 +384,7 @@ impl MacInterface { data: ControlIn, timeout: Duration, ) -> impl MaybeFuture, TransferError>> { - self.device.control_in(data, timeout) + self.device.clone().control_in(data, timeout) } pub fn control_out( @@ -390,7 +392,7 @@ impl MacInterface { data: ControlOut, timeout: Duration, ) -> impl MaybeFuture> { - self.device.control_out(data, timeout) + self.device.clone().control_out(data, timeout) } pub fn endpoint(