devices: virtio: console: use ReadNotifier trait for polling

AsRawDescriptor is a very generic trait and some of the types we want to
use as input sources already implement it for other purposes.
ReadNotifier makes the purpose of the returned descriptor obvious (wait
for some data), so use it instead.

BUG=b:228912920
TEST=console device works in both regular and vhost-user modes.

Change-Id: I68a4ce05be449e07ea71e7cb472e8cda00e9d84d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3671059
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
This commit is contained in:
Alexandre Courbot 2022-05-27 13:25:58 +09:00 committed by Chromeos LUCI
parent 947754f011
commit 8297d745c6
5 changed files with 37 additions and 16 deletions

View file

@ -10,6 +10,12 @@ pub trait ReadNotifier {
fn get_read_notifier(&self) -> &dyn AsRawDescriptor;
}
impl ReadNotifier for std::fs::File {
fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
self
}
}
pub trait CloseNotifier {
/// Gets a descriptor that can be used in EventContext to wait for the closed event.
fn get_close_notifier(&self) -> &dyn AsRawDescriptor;

View file

@ -2,16 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::io::{stdin, Error, Read, Result};
use std::io::{Error, Read, Result};
use winapi::{
shared::{minwindef::LPVOID, ntdef::NULL},
um::{fileapi::ReadFile, minwinbase::LPOVERLAPPED},
};
use crate::{AsRawDescriptor, RawDescriptor};
use crate::{AsRawDescriptor, ReadNotifier};
pub struct Console;
pub struct Console(std::io::Stdin);
impl Console {
pub fn new() -> Self {
Self(std::io::stdin())
}
}
impl Read for Console {
fn read(&mut self, out: &mut [u8]) -> Result<usize> {
@ -20,7 +26,7 @@ impl Read for Console {
// and `num_of_bytes_read` is a valid u32.
let res = unsafe {
ReadFile(
stdin().as_raw_descriptor(),
self.0.as_raw_descriptor(),
out.as_mut_ptr() as LPVOID,
out.len() as u32,
&mut num_of_bytes_read,
@ -36,8 +42,8 @@ impl Read for Console {
}
}
impl AsRawDescriptor for Console {
fn as_raw_descriptor(&self) -> RawDescriptor {
stdin().as_raw_descriptor()
impl ReadNotifier for Console {
fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
&self.0
}
}

View file

@ -9,7 +9,9 @@ use std::path::PathBuf;
#[cfg(windows)]
use base::platform::Console as WinConsole;
use base::{error, open_file, syslog, AsRawDescriptor, Event, FileSync, RawDescriptor};
use base::{
error, open_file, syslog, AsRawDescriptor, Event, FileSync, RawDescriptor, ReadNotifier,
};
use hypervisor::ProtectionType;
use remain::sorted;
use serde::{Deserialize, Serialize};
@ -42,7 +44,7 @@ pub enum Error {
}
/// Trait for types that can be used as input for a serial device.
pub trait SerialInput: io::Read + AsRawDescriptor + Send {}
pub trait SerialInput: io::Read + ReadNotifier + Send {}
impl SerialInput for File {}
#[cfg(windows)]
impl SerialInput for WinConsole {}
@ -159,7 +161,7 @@ impl SerialParameters {
Some(Box::new(input_file))
} else if self.stdin {
keep_rds.push(stdin().as_raw_descriptor());
Some(Box::new(ConsoleInput))
Some(Box::new(ConsoleInput::new()))
} else {
None
};

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use base::{error, AsRawDescriptor, Event, FileSync, RawDescriptor};
use base::{error, AsRawDescriptor, Event, FileSync, RawDescriptor, ReadNotifier};
use base::{info, read_raw_stdin};
use hypervisor::ProtectionType;
use std::borrow::Cow;
@ -20,16 +20,23 @@ pub const SYSTEM_SERIAL_TYPE_NAME: &str = "UnixSocket";
// This wrapper is used in place of the libstd native version because we don't want
// buffering for stdin.
pub struct ConsoleInput;
pub struct ConsoleInput(std::io::Stdin);
impl ConsoleInput {
pub fn new() -> Self {
Self(std::io::stdin())
}
}
impl io::Read for ConsoleInput {
fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
read_raw_stdin(out).map_err(|e| e.into())
}
}
impl AsRawDescriptor for ConsoleInput {
fn as_raw_descriptor(&self) -> RawDescriptor {
std::io::stdin().as_raw_descriptor()
impl ReadNotifier for ConsoleInput {
fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
&self.0
}
}

View file

@ -33,7 +33,7 @@ use super::{handle_input, process_transmit_queue, QUEUE_SIZES};
struct AsyncSerialInput(Box<dyn SerialInput>);
impl AsRawDescriptor for AsyncSerialInput {
fn as_raw_descriptor(&self) -> RawDescriptor {
self.0.as_raw_descriptor()
self.0.get_read_notifier().as_raw_descriptor()
}
}
impl IntoAsync for AsyncSerialInput {}