/src/crosvm/cros_async/src/audio_streams_async.rs
Line | Count | Source (jump to first uncovered line) |
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 | | //! Implements the interface required by `audio_streams` using the cros_async Executor. |
6 | | //! |
7 | | //! It implements the `AudioStreamsExecutor` trait for `Executor`, so it can be passed into |
8 | | //! the audio_streams API. |
9 | | use std::io::Result; |
10 | | #[cfg(any(target_os = "android", target_os = "linux"))] |
11 | | use std::os::unix::net::UnixStream; |
12 | | #[cfg(windows)] |
13 | | use std::os::windows::io::RawHandle; |
14 | | use std::time::Duration; |
15 | | |
16 | | use async_trait::async_trait; |
17 | | #[cfg(any(target_os = "android", target_os = "linux"))] |
18 | | use audio_streams::async_api::AsyncStream; |
19 | | use audio_streams::async_api::AudioStreamsExecutor; |
20 | | use audio_streams::async_api::EventAsyncWrapper; |
21 | | use audio_streams::async_api::ReadAsync; |
22 | | use audio_streams::async_api::ReadWriteAsync; |
23 | | use audio_streams::async_api::WriteAsync; |
24 | | #[cfg(any(target_os = "android", target_os = "linux"))] |
25 | | use base::Descriptor; |
26 | | #[cfg(windows)] |
27 | | use base::Event; |
28 | | #[cfg(windows)] |
29 | | use base::FromRawDescriptor; |
30 | | #[cfg(any(target_os = "android", target_os = "linux"))] |
31 | | use base::RawDescriptor; |
32 | | |
33 | | #[cfg(any(target_os = "android", target_os = "linux"))] |
34 | | use super::AsyncWrapper; |
35 | | use crate::EventAsync; |
36 | | use crate::IntoAsync; |
37 | | use crate::IoSource; |
38 | | use crate::TimerAsync; |
39 | | |
40 | | /// A wrapper around IoSource that is compatible with the audio_streams traits. |
41 | | pub struct IoSourceWrapper<T: IntoAsync + Send> { |
42 | | source: IoSource<T>, |
43 | | } |
44 | | |
45 | | #[async_trait(?Send)] |
46 | | impl<T: IntoAsync + Send> ReadAsync for IoSourceWrapper<T> { |
47 | 0 | async fn read_to_vec<'a>( |
48 | 0 | &'a self, |
49 | 0 | file_offset: Option<u64>, |
50 | 0 | vec: Vec<u8>, |
51 | 0 | ) -> Result<(usize, Vec<u8>)> { |
52 | 0 | self.source |
53 | 0 | .read_to_vec(file_offset, vec) |
54 | 0 | .await |
55 | 0 | .map_err(Into::into) |
56 | 0 | } |
57 | | } |
58 | | |
59 | | #[async_trait(?Send)] |
60 | | impl<T: IntoAsync + Send> WriteAsync for IoSourceWrapper<T> { |
61 | 0 | async fn write_from_vec<'a>( |
62 | 0 | &'a self, |
63 | 0 | file_offset: Option<u64>, |
64 | 0 | vec: Vec<u8>, |
65 | 0 | ) -> Result<(usize, Vec<u8>)> { |
66 | 0 | self.source |
67 | 0 | .write_from_vec(file_offset, vec) |
68 | 0 | .await |
69 | 0 | .map_err(Into::into) |
70 | 0 | } |
71 | | } |
72 | | |
73 | | #[async_trait(?Send)] |
74 | | impl<T: IntoAsync + Send> ReadWriteAsync for IoSourceWrapper<T> {} |
75 | | |
76 | | #[async_trait(?Send)] |
77 | | impl EventAsyncWrapper for EventAsync { |
78 | 0 | async fn wait(&self) -> Result<u64> { |
79 | 0 | self.next_val().await.map_err(Into::into) |
80 | 0 | } |
81 | | } |
82 | | |
83 | | #[async_trait(?Send)] |
84 | | impl AudioStreamsExecutor for super::Executor { |
85 | | #[cfg(any(target_os = "android", target_os = "linux"))] |
86 | 0 | fn async_unix_stream(&self, stream: UnixStream) -> Result<AsyncStream> { |
87 | 0 | Ok(Box::new(IoSourceWrapper { |
88 | 0 | source: self.async_from(AsyncWrapper::new(stream))?, |
89 | | })) |
90 | 0 | } |
91 | | |
92 | | /// # Safety |
93 | | /// This is only safe if `event` is a handle to a Windows Event. |
94 | | #[cfg(windows)] |
95 | | unsafe fn async_event(&self, event: RawHandle) -> Result<Box<dyn EventAsyncWrapper>> { |
96 | | Ok(Box::new( |
97 | | EventAsync::new(Event::from_raw_descriptor(event), self) |
98 | | .map_err(std::io::Error::from)?, |
99 | | )) |
100 | | } |
101 | | |
102 | 0 | async fn delay(&self, dur: Duration) -> Result<()> { |
103 | 0 | TimerAsync::sleep(self, dur).await.map_err(Into::into) |
104 | 0 | } |
105 | | |
106 | | #[cfg(any(target_os = "android", target_os = "linux"))] |
107 | 0 | async fn wait_fd_readable(&self, fd: RawDescriptor) -> Result<()> { |
108 | 0 | self.async_from(AsyncWrapper::new(Descriptor(fd)))? |
109 | 0 | .wait_readable() |
110 | 0 | .await |
111 | 0 | .map_err(Into::into) |
112 | 0 | } |
113 | | } |