MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / poll_read

Method poll_read

crates/wasi/src/cli/worker_thread_stdin.rs:222–295  ·  view source on GitHub ↗
(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut ReadBuf<'_>,
    )

Source from the content-addressed store, hash-verified

220
221impl AsyncRead for WasiStdinAsyncRead {
222 fn poll_read(
223 mut self: Pin<&mut Self>,
224 cx: &mut Context<'_>,
225 buf: &mut ReadBuf<'_>,
226 ) -> Poll<io::Result<()>> {
227 let g = GlobalStdin::get();
228
229 // Everything below is executed under the global stdin lock. It's not
230 // going to block below so that's semantically fine. Optimization-wise
231 // it's probably possible to move this within the loop around just a
232 // small part of reading/writing the state, but that was done
233 // historically and it resulted in lost wakeups with `Notify`, so this
234 // is conservatively hoisted up here.
235 let mut locked = g.state.lock().unwrap();
236
237 // Perform everything below in a `loop` to handle the case that a read
238 // was stolen by another thread, for example, or perhaps a spurious
239 // notification to `Notified`.
240 loop {
241 // If we were previously blocked on reading a "ready" notification,
242 // wait for that notification to complete.
243 if let Some(notified) = self.as_mut().notified_future() {
244 match notified.poll(cx) {
245 Poll::Ready(()) => self.set(WasiStdinAsyncRead::Ready),
246 Poll::Pending => break Poll::Pending,
247 }
248 }
249
250 assert!(matches!(*self, WasiStdinAsyncRead::Ready));
251
252 // Once we're in the "ready" state then take a look at the global
253 // state of stdin.
254 match mem::replace(&mut *locked, StdinState::ReadRequested(buf.remaining())) {
255 // If data is available then drain what we can into `buf`.
256 StdinState::Data(mut data) => {
257 let size = data.len().min(buf.remaining());
258 let bytes = data.split_to(size);
259 *locked = if data.is_empty() {
260 StdinState::ReadNotRequested
261 } else {
262 StdinState::Data(data)
263 };
264 buf.put_slice(&bytes);
265 break Poll::Ready(Ok(()));
266 }
267
268 // If stdin failed to be read then we fail with that error and
269 // transition to "closed"
270 StdinState::Error(e) => {
271 *locked = StdinState::Closed;
272 break Poll::Ready(Err(e));
273 }
274
275 // If stdin is closed, keep it closed.
276 StdinState::Closed => {
277 *locked = StdinState::Closed;
278 break Poll::Ready(Ok(()));
279 }

Callers

nothing calls this directly

Calls 15

DataClass · 0.85
OkFunction · 0.85
notified_futureMethod · 0.80
getFunction · 0.50
replaceFunction · 0.50
unwrapMethod · 0.45
lockMethod · 0.45
as_mutMethod · 0.45
pollMethod · 0.45
setMethod · 0.45
remainingMethod · 0.45
minMethod · 0.45

Tested by

no test coverage detected