• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use anyhow::Context;
6 use anyhow::Result;
7 use base::info;
8 use base::AsRawDescriptor;
9 use base::SafeDescriptor;
10 use cros_async::AsyncWrapper;
11 use cros_async::Executor;
12 use vmm_vhost::BackendServer;
13 use vmm_vhost::Error as VhostError;
14 
15 /// Performs the run loop for an already-constructor request handler.
run_handler<S>(mut backend_server: BackendServer<S>, ex: &Executor) -> Result<()> where S: vmm_vhost::Backend,16 pub async fn run_handler<S>(mut backend_server: BackendServer<S>, ex: &Executor) -> Result<()>
17 where
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                 // Exit as the client closed the connection.
37                 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 }
53