devices/virtio/vhost_user_backend/handler/sys/
linux.rs1use anyhow::Context;
6use anyhow::Result;
7use base::info;
8use base::AsRawDescriptor;
9use base::SafeDescriptor;
10use cros_async::AsyncWrapper;
11use cros_async::Executor;
12use vmm_vhost::BackendServer;
13use vmm_vhost::Error as VhostError;
14
15pub async fn run_handler<S>(mut backend_server: BackendServer<S>, ex: &Executor) -> Result<()>
17where
18 S: vmm_vhost::Backend,
19{
20 let h = SafeDescriptor::try_from(&backend_server as &dyn AsRawDescriptor)
21 .map(AsyncWrapper::new)
22 .context("failed to get safe descriptor for handler")?;
23 let handler_source = ex
24 .async_from(h)
25 .context("failed to create an async source")?;
26
27 loop {
28 handler_source
29 .wait_readable()
30 .await
31 .context("failed to wait for the handler to become readable")?;
32 let (hdr, files) = match backend_server.recv_header() {
33 Ok((hdr, files)) => (hdr, files),
34 Err(VhostError::ClientExit) => {
35 info!("vhost-user connection closed");
36 return Ok(());
38 }
39 Err(e) => {
40 return Err(e.into());
41 }
42 };
43
44 if backend_server.needs_wait_for_payload(&hdr) {
45 handler_source
46 .wait_readable()
47 .await
48 .context("failed to wait for the handler to become readable")?;
49 }
50 backend_server.process_message(hdr, files)?;
51 }
52}