mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 06:08:29 +00:00
WIP: prepare buffered reads to Pipe instead of reading data on-demand
This commit is contained in:
@@ -60,9 +60,47 @@ pub struct wasi_pipe_t {
|
|||||||
|
|
||||||
struct WasiPipeDataWithDestructor {
|
struct WasiPipeDataWithDestructor {
|
||||||
data: Vec<c_char>,
|
data: Vec<c_char>,
|
||||||
|
// Buffer of already-read data that is being read into,
|
||||||
|
// then the result is returned
|
||||||
|
temp_buffer: Vec<u8>,
|
||||||
destructor: WasiConsoleIoEnvDestructor,
|
destructor: WasiConsoleIoEnvDestructor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WasiPipeDataWithDestructor {
|
||||||
|
fn read_buffer(&mut self, read_cb: WasiConsoleIoReadCallback, max_read: Option<usize>) -> io::Result<Vec<u8>> {
|
||||||
|
|
||||||
|
const BLOCK_SIZE: usize = 1024;
|
||||||
|
|
||||||
|
let mut final_buf = Vec::new();
|
||||||
|
|
||||||
|
match max_read {
|
||||||
|
None => {
|
||||||
|
// read from pipe until EOF encountered
|
||||||
|
},
|
||||||
|
Some(max) => {
|
||||||
|
// read from pipe until either EOF or maximum number of bytes
|
||||||
|
for i in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
let result = unsafe {
|
||||||
|
let ptr = buf.as_mut_ptr() as *mut c_char;
|
||||||
|
(self_read)(data.data.as_mut_ptr() as *const c_void, ptr, buf.len())
|
||||||
|
};
|
||||||
|
if result >= 0 {
|
||||||
|
Ok(result as usize)
|
||||||
|
} else {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!("could not read from wasi_pipe_t: {result}"),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Drop for WasiPipeDataWithDestructor {
|
impl Drop for WasiPipeDataWithDestructor {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let error = unsafe { (self.destructor)(self.data.as_mut_ptr() as *const c_void) };
|
let error = unsafe { (self.destructor)(self.data.as_mut_ptr() as *const c_void) };
|
||||||
@@ -73,6 +111,15 @@ impl Drop for WasiPipeDataWithDestructor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl wasi_pipe_t {
|
impl wasi_pipe_t {
|
||||||
|
|
||||||
|
/// Read bytes from this pipe into the internal buffer,
|
||||||
|
/// returning how many bytes were read
|
||||||
|
fn read_from_pipe_store_in_buffer(&self) -> io::Result<usize> {
|
||||||
|
let mut data = self.get_data_mut("read_from_pipe")?;
|
||||||
|
data.read_into_buffer();
|
||||||
|
Ok(data.temp_buffer.len())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_data_mut(
|
fn get_data_mut(
|
||||||
&self,
|
&self,
|
||||||
op_id: &'static str,
|
op_id: &'static str,
|
||||||
@@ -105,17 +152,8 @@ impl io::Read for wasi_pipe_t {
|
|||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let self_read = self.read;
|
let self_read = self.read;
|
||||||
let mut data = self.get_data_mut("read")?;
|
let mut data = self.get_data_mut("read")?;
|
||||||
let result = unsafe {
|
if data.temp_buffer.len() >= buf.len() {
|
||||||
let ptr = buf.as_mut_ptr() as *mut c_char;
|
// fill up buf by draining temp_buffer first, then read more bytes
|
||||||
(self_read)(data.data.as_mut_ptr() as *const c_void, ptr, buf.len())
|
|
||||||
};
|
|
||||||
if result >= 0 {
|
|
||||||
Ok(result as usize)
|
|
||||||
} else {
|
|
||||||
Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("could not read from wasi_pipe_t: {result}"),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,7 +250,7 @@ impl VirtualFile for wasi_pipe_t {
|
|||||||
+ self.bytes_available_write()?.unwrap_or(0usize))
|
+ self.bytes_available_write()?.unwrap_or(0usize))
|
||||||
}
|
}
|
||||||
fn bytes_available_read(&self) -> Result<Option<usize>, FsError> {
|
fn bytes_available_read(&self) -> Result<Option<usize>, FsError> {
|
||||||
Ok(None)
|
let read = self.read_from_pipe_store_in_buffer();
|
||||||
}
|
}
|
||||||
fn bytes_available_write(&self) -> Result<Option<usize>, FsError> {
|
fn bytes_available_write(&self) -> Result<Option<usize>, FsError> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -237,6 +275,7 @@ pub unsafe extern "C" fn wasi_pipe_new_internal(
|
|||||||
seek,
|
seek,
|
||||||
data: Some(Box::new(Arc::new(Mutex::new(WasiPipeDataWithDestructor {
|
data: Some(Box::new(Arc::new(Mutex::new(WasiPipeDataWithDestructor {
|
||||||
data: data_vec,
|
data: data_vec,
|
||||||
|
temp_buffer: Vec::new(),
|
||||||
destructor,
|
destructor,
|
||||||
})))),
|
})))),
|
||||||
}))
|
}))
|
||||||
@@ -461,15 +500,17 @@ pub unsafe extern "C" fn wasi_pipe_delete_str(buf: *mut c_char) {
|
|||||||
let _ = CString::from_raw(buf);
|
let _ = CString::from_raw(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
unsafe fn wasi_pipe_read_bytes_internal(
|
||||||
pub unsafe extern "C" fn wasi_pipe_read_str(ptr: *const wasi_pipe_t, buf: *mut *mut c_char) -> i64 {
|
ptr: *const wasi_pipe_t,
|
||||||
use std::ffi::CString;
|
buf: &mut Vec<u8>
|
||||||
|
) -> i64 {
|
||||||
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
const BLOCK_SIZE: usize = 1024;
|
const BLOCK_SIZE: usize = 1024;
|
||||||
|
|
||||||
let mut target = Vec::new();
|
|
||||||
let ptr = &mut *(ptr as *mut wasi_pipe_t);
|
let ptr = &mut *(ptr as *mut wasi_pipe_t);
|
||||||
|
let mut target = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut v = vec![0; BLOCK_SIZE];
|
let mut v = vec![0; BLOCK_SIZE];
|
||||||
@@ -487,6 +528,20 @@ pub unsafe extern "C" fn wasi_pipe_read_str(ptr: *const wasi_pipe_t, buf: *mut *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*buf = target;
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasi_pipe_read_str(ptr: *const wasi_pipe_t, buf: *mut *mut c_char) -> i64 {
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
|
let mut target = Vec::new();
|
||||||
|
let read_result = wasi_pipe_read_bytes_internal(ptr, &mut target);
|
||||||
|
if read_result < 0 {
|
||||||
|
return read_result;
|
||||||
|
}
|
||||||
|
|
||||||
target.push(0);
|
target.push(0);
|
||||||
let len = target.len();
|
let len = target.len();
|
||||||
let c_string = match CString::from_vec_with_nul(target.clone()) {
|
let c_string = match CString::from_vec_with_nul(target.clone()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user