|
1 | 1 | use super::{AsyncPollable, AsyncRead, AsyncWrite}; |
2 | | -use std::cell::RefCell; |
| 2 | +use std::cell::OnceCell; |
3 | 3 | use std::io::Result; |
4 | 4 | use wasi::io::streams::{InputStream, OutputStream, StreamError}; |
5 | 5 |
|
6 | 6 | #[derive(Debug)] |
7 | 7 | pub struct AsyncInputStream { |
8 | 8 | // Lazily initialized pollable, used for lifetime of stream to check readiness. |
9 | 9 | // Field ordering matters: this child must be dropped before stream |
10 | | - subscription: RefCell<Option<AsyncPollable>>, |
| 10 | + subscription: OnceCell<AsyncPollable>, |
11 | 11 | stream: InputStream, |
12 | 12 | } |
13 | 13 |
|
14 | 14 | impl AsyncInputStream { |
15 | 15 | pub fn new(stream: InputStream) -> Self { |
16 | 16 | Self { |
17 | | - subscription: RefCell::new(None), |
| 17 | + subscription: OnceCell::new(), |
18 | 18 | stream, |
19 | 19 | } |
20 | 20 | } |
21 | 21 | async fn ready(&self) { |
22 | 22 | // Lazily initialize the AsyncPollable |
23 | | - if self.subscription.borrow().is_none() { |
24 | | - self.subscription |
25 | | - .replace(Some(AsyncPollable::new(self.stream.subscribe()))); |
26 | | - } |
| 23 | + let subscription = self |
| 24 | + .subscription |
| 25 | + .get_or_init(|| AsyncPollable::new(self.stream.subscribe())); |
27 | 26 | // Wait on readiness |
28 | | - self.subscription |
29 | | - .borrow() |
30 | | - .as_ref() |
31 | | - .expect("populated refcell") |
32 | | - .wait_for() |
33 | | - .await; |
| 27 | + subscription.wait_for().await; |
34 | 28 | } |
35 | 29 | /// Like [`AsyncRead::read`], but doesn't require a `&mut self`. |
36 | 30 | pub async fn read(&self, buf: &mut [u8]) -> Result<usize> { |
@@ -70,30 +64,24 @@ impl AsyncRead for AsyncInputStream { |
70 | 64 | pub struct AsyncOutputStream { |
71 | 65 | // Lazily initialized pollable, used for lifetime of stream to check readiness. |
72 | 66 | // Field ordering matters: this child must be dropped before stream |
73 | | - subscription: RefCell<Option<AsyncPollable>>, |
| 67 | + subscription: OnceCell<AsyncPollable>, |
74 | 68 | stream: OutputStream, |
75 | 69 | } |
76 | 70 |
|
77 | 71 | impl AsyncOutputStream { |
78 | 72 | pub fn new(stream: OutputStream) -> Self { |
79 | 73 | Self { |
80 | | - subscription: RefCell::new(None), |
| 74 | + subscription: OnceCell::new(), |
81 | 75 | stream, |
82 | 76 | } |
83 | 77 | } |
84 | 78 | async fn ready(&self) { |
85 | 79 | // Lazily initialize the AsyncPollable |
86 | | - if self.subscription.borrow().is_none() { |
87 | | - self.subscription |
88 | | - .replace(Some(AsyncPollable::new(self.stream.subscribe()))); |
89 | | - } |
| 80 | + let subscription = self |
| 81 | + .subscription |
| 82 | + .get_or_init(|| AsyncPollable::new(self.stream.subscribe())); |
90 | 83 | // Wait on readiness |
91 | | - self.subscription |
92 | | - .borrow() |
93 | | - .as_ref() |
94 | | - .expect("populated refcell") |
95 | | - .wait_for() |
96 | | - .await; |
| 84 | + subscription.wait_for().await; |
97 | 85 | } |
98 | 86 | /// Like [`AsyncWrite::write`], but doesn't require a `&mut self`. |
99 | 87 | pub async fn write(&self, buf: &[u8]) -> Result<usize> { |
|
0 commit comments