Next Generation WASM Microkernel Operating System

feat: async IO traits #3

open opened by jonaskruckenberg.de targeting main from jonas/refactor/mem
Labels

None yet.

Participants 1
AT URI
at://did:plc:wur5mmsnhlocanyqtus3oex5/sh.tangled.repo.pull/3lwcqoxo4gg22
+221
Diff #2
+220
libs/kasync/src/io.rs
··· 1 + // Copyright 2025. Jonas Kruckenberg 2 + // 3 + // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4 + // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5 + // http://opensource.org/licenses/MIT>, at your option. This file may not be 6 + // copied, modified, or distributed except according to those terms. 7 + 8 + use core::cmp; 9 + use core::convert::Infallible; 10 + use core::ops::{Deref, DerefMut}; 11 + use core::pin::Pin; 12 + use core::task::{Context, Poll, ready}; 13 + 14 + pub trait Read { 15 + type Err: core::error::Error; 16 + 17 + // Pull some bytes from this source into the specified buffer. 18 + fn poll_read( 19 + self: Pin<&mut Self>, 20 + cx: &mut Context<'_>, 21 + buf: &mut [u8], 22 + ) -> Poll<Result<usize, Self::Err>>; 23 + 24 + // Attempt to read from the AsyncRead into bufs using vectored IO operations. 25 + // 26 + // This method is similar to poll_read, but allows data to be read into multiple buffers using a single operation. 27 + // 28 + // On success, returns Poll::Ready(Ok(num_bytes_read)). 29 + fn poll_read_vectored( 30 + mut self: Pin<&mut Self>, 31 + cx: &mut Context<'_>, 32 + bufs: &mut [&mut [u8]], 33 + ) -> Poll<Result<usize, Self::Err>> { 34 + let mut nread = 0; 35 + for b in bufs { 36 + if !b.is_empty() { 37 + nread += ready!(self.as_mut().poll_read(cx, b)?); 38 + } 39 + } 40 + Poll::Ready(Ok(nread)) 41 + } 42 + } 43 + 44 + pub trait Write { 45 + type Err: core::error::Error; 46 + 47 + // Writes a buffer into this writer. 48 + // 49 + // returning how many bytes were written. 50 + fn poll_write( 51 + self: Pin<&mut Self>, 52 + cx: &mut Context<'_>, 53 + buf: &[u8], 54 + ) -> Poll<Result<usize, Self::Err>>; 55 + 56 + // Flushes this output stream, ensuring that all intermediately buffered contents reach their destination. 57 + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>>; 58 + 59 + // Attempt to close the object. 60 + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>>; 61 + 62 + // Attempt to write bytes from bufs into the object using vectored IO operations. 63 + // 64 + // This method is similar to poll_write, but allows data from multiple buffers to be written using a single operation. 65 + // 66 + // On success, returns Poll::Ready(Ok(num_bytes_written)). 67 + fn poll_write_vectored( 68 + mut self: Pin<&mut Self>, 69 + cx: &mut Context<'_>, 70 + bufs: &[&[u8]], 71 + ) -> Poll<Result<usize, Self::Err>> { 72 + let mut nwritten = 0; 73 + for b in bufs { 74 + if !b.is_empty() { 75 + nwritten += ready!(self.as_mut().poll_write(cx, b)?); 76 + } 77 + } 78 + Poll::Ready(Ok(nwritten)) 79 + } 80 + } 81 + 82 + // ===== impl Read ===== 83 + 84 + impl Read for &[u8] { 85 + type Err = Infallible; 86 + 87 + fn poll_read( 88 + self: Pin<&mut Self>, 89 + _cx: &mut Context<'_>, 90 + buf: &mut [u8], 91 + ) -> Poll<Result<usize, Self::Err>> { 92 + let amt = cmp::min(buf.len(), self.len()); 93 + let (a, b) = self.split_at(amt); 94 + 95 + // First check if the amount of bytes we want to read is small: 96 + // `copy_from_slice` will generally expand to a call to `memcpy`, and 97 + // for a single byte the overhead is significant. 98 + if amt == 1 { 99 + buf[0] = a[0]; 100 + } else { 101 + buf[..amt].copy_from_slice(a); 102 + } 103 + 104 + *self.get_mut() = b; 105 + 106 + Poll::Ready(Ok(amt)) 107 + } 108 + } 109 + 110 + impl<P> Read for Pin<P> 111 + where 112 + P: DerefMut + Unpin, 113 + <P as Deref>::Target: Read, 114 + { 115 + type Err = <P::Target as Read>::Err; 116 + 117 + fn poll_read( 118 + self: Pin<&mut Self>, 119 + cx: &mut Context<'_>, 120 + buf: &mut [u8], 121 + ) -> Poll<Result<usize, Self::Err>> { 122 + self.get_mut().as_mut().poll_read(cx, buf) 123 + } 124 + 125 + fn poll_read_vectored( 126 + self: Pin<&mut Self>, 127 + cx: &mut Context<'_>, 128 + bufs: &mut [&mut [u8]], 129 + ) -> Poll<Result<usize, Self::Err>> { 130 + self.get_mut().as_mut().poll_read_vectored(cx, bufs) 131 + } 132 + } 133 + 134 + impl<T> Read for &mut T 135 + where 136 + T: Read + Unpin + ?Sized, 137 + { 138 + type Err = T::Err; 139 + 140 + fn poll_read( 141 + mut self: Pin<&mut Self>, 142 + cx: &mut Context<'_>, 143 + buf: &mut [u8], 144 + ) -> Poll<Result<usize, Self::Err>> { 145 + Pin::new(&mut **self).poll_read(cx, buf) 146 + } 147 + 148 + fn poll_read_vectored( 149 + mut self: Pin<&mut Self>, 150 + cx: &mut Context<'_>, 151 + bufs: &mut [&mut [u8]], 152 + ) -> Poll<Result<usize, Self::Err>> { 153 + Pin::new(&mut **self).poll_read_vectored(cx, bufs) 154 + } 155 + } 156 + 157 + // ===== impl Write ===== 158 + 159 + impl<P> Write for Pin<P> 160 + where 161 + P: DerefMut + Unpin, 162 + <P as Deref>::Target: Write, 163 + { 164 + type Err = <P::Target as Write>::Err; 165 + 166 + fn poll_write( 167 + self: Pin<&mut Self>, 168 + cx: &mut Context<'_>, 169 + buf: &[u8], 170 + ) -> Poll<Result<usize, Self::Err>> { 171 + self.get_mut().as_mut().poll_write(cx, buf) 172 + } 173 + 174 + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> { 175 + self.get_mut().as_mut().poll_flush(cx) 176 + } 177 + 178 + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> { 179 + self.get_mut().as_mut().poll_close(cx) 180 + } 181 + 182 + fn poll_write_vectored( 183 + self: Pin<&mut Self>, 184 + cx: &mut Context<'_>, 185 + bufs: &[&[u8]], 186 + ) -> Poll<Result<usize, Self::Err>> { 187 + self.get_mut().as_mut().poll_write_vectored(cx, bufs) 188 + } 189 + } 190 + 191 + impl<T> Write for &mut T 192 + where 193 + T: Write + Unpin + ?Sized, 194 + { 195 + type Err = T::Err; 196 + 197 + fn poll_write( 198 + mut self: Pin<&mut Self>, 199 + cx: &mut Context<'_>, 200 + buf: &[u8], 201 + ) -> Poll<Result<usize, Self::Err>> { 202 + Pin::new(&mut **self).poll_write(cx, buf) 203 + } 204 + 205 + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> { 206 + Pin::new(&mut **self).poll_flush(cx) 207 + } 208 + 209 + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> { 210 + Pin::new(&mut **self).poll_close(cx) 211 + } 212 + 213 + fn poll_write_vectored( 214 + mut self: Pin<&mut Self>, 215 + cx: &mut Context<'_>, 216 + bufs: &[&[u8]], 217 + ) -> Poll<Result<usize, Self::Err>> { 218 + Pin::new(&mut **self).poll_write_vectored(cx, bufs) 219 + } 220 + }
+1
libs/kasync/src/lib.rs
··· 17 17 18 18 mod error; 19 19 pub mod executor; 20 + pub mod io; 20 21 pub mod loom; 21 22 pub mod sync; 22 23 pub mod task;

History

3 rounds 0 comments
sign up or login to add to the discussion
1 commit
expand
feat: async IO traits
no conflicts, ready to merge
expand 0 comments
1 commit
expand
feat: async IO traits
expand 0 comments
1 commit
expand
feat: async IO traits
expand 0 comments