usbip-rs/lib/examples/cdc_acm_serial.rs
Davíð Steinn Geirsson 4c368c02b5 feat: concurrent ISO pipelining via nusb update and &self handlers
Update nusb to c1380673 which allows multiple IsoEndpoint instances per
address, enabling concurrent URB submission from separate threads.

Change UsbInterfaceHandler trait methods from &mut self to &self and
replace Arc<Mutex<Box<dyn Handler>>> with Arc<dyn Handler>. This
removes the serialization bottleneck where the handler mutex was held
for the entire USB transfer duration, causing ISO audio to play at
~67% speed.

Handlers needing interior mutability (HID, CDC) now use Mutex on
individual fields. Passthrough handlers already used Arc<Mutex<>>
internally and need no changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 15:10:28 +00:00

32 lines
1 KiB
Rust

use log::*;
use std::net::*;
use std::sync::Arc;
use std::time::Duration;
#[tokio::main]
async fn main() {
env_logger::init();
let handler = Arc::new(usbip_rs::cdc::UsbCdcAcmHandler::new());
let server = Arc::new(usbip_rs::UsbIpServer::new_simulated(vec![
usbip_rs::UsbDevice::new(0)
.expect("create device")
.with_interface(
usbip_rs::ClassCode::CDC as u8,
usbip_rs::cdc::CDC_ACM_SUBCLASS,
0x00,
Some("Test CDC ACM"),
usbip_rs::cdc::UsbCdcAcmHandler::endpoints(),
handler.clone() as Arc<dyn usbip_rs::UsbInterfaceHandler>,
)
.expect("add interface"),
]));
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 3240);
tokio::spawn(usbip_rs::server(addr, server));
loop {
// sleep 1s
tokio::time::sleep(Duration::new(1, 0)).await;
handler.tx_buffer.lock().unwrap().push(b'a');
info!("Simulate a char input");
}
}