diff --git a/core/01_core.js b/core/01_core.js index c46c300700..ab54316e59 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -412,6 +412,8 @@ readAll: opAsync.bind(null, "op_read_all"), write: opAsync.bind(null, "op_write"), writeAll: opAsync.bind(null, "op_write_all"), + readSync: (rid, buffer) => ops.op_read_sync(rid, buffer), + writeSync: (rid, buffer) => ops.op_write_sync(rid, buffer), shutdown: opAsync.bind(null, "op_shutdown"), print: (msg, isErr) => ops.op_print(msg, isErr), setMacrotaskCallback: (fn) => ops.op_set_macrotask_callback(fn), diff --git a/core/lib.deno_core.d.ts b/core/lib.deno_core.d.ts index b238bd6b31..7f3ea2a191 100644 --- a/core/lib.deno_core.d.ts +++ b/core/lib.deno_core.d.ts @@ -60,6 +60,16 @@ declare namespace Deno { */ function writeAll(rid: number, buf: Uint8Array): Promise; + /** + * Synchronously read from a (stream) resource that implements readSync(). + */ + function readSync(rid: number, buf: Uint8Array): number; + + /** + * Synchronously write to a (stream) resource that implements writeSync(). + */ + function writeSync(rid: number, buf: Uint8Array): number; + /** * Print a message to stdout or stderr */ diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs index 668b44bc36..7f9c48e01b 100644 --- a/core/ops_builtin.rs +++ b/core/ops_builtin.rs @@ -33,6 +33,8 @@ crate::extension!( op_read, op_read_all, op_write, + op_read_sync, + op_write_sync, op_write_all, op_shutdown, op_metrics, @@ -279,6 +281,27 @@ async fn op_write( Ok(resp.nwritten() as u32) } +#[op(fast)] +fn op_read_sync( + state: &mut OpState, + rid: ResourceId, + data: &mut [u8], +) -> Result { + let resource = state.resource_table.get_any(rid)?; + resource.read_byob_sync(data).map(|n| n as u32) +} + +#[op] +fn op_write_sync( + state: &mut OpState, + rid: ResourceId, + data: &[u8], +) -> Result { + let resource = state.resource_table.get_any(rid)?; + let nwritten = resource.write_sync(data)?; + Ok(nwritten as u32) +} + #[op] async fn op_write_all( state: Rc>, diff --git a/core/resources.rs b/core/resources.rs index 5bec684810..6ca86e10b6 100644 --- a/core/resources.rs +++ b/core/resources.rs @@ -154,6 +154,18 @@ pub trait Resource: Any + 'static { }) } + /// The same as [`read_byob()`][Resource::read_byob], but synchronous. + fn read_byob_sync(&self, data: &mut [u8]) -> Result { + _ = data; + Err(not_supported()) + } + + /// The same as [`write()`][Resource::write], but synchronous. + fn write_sync(&self, data: &[u8]) -> Result { + _ = data; + Err(not_supported()) + } + /// The shutdown method can be used to asynchronously close the resource. It /// is not automatically called when the resource is dropped or closed. /// diff --git a/ext/io/12_io.js b/ext/io/12_io.js index 2a825e7f65..1bb8f9fba9 100644 --- a/ext/io/12_io.js +++ b/ext/io/12_io.js @@ -93,27 +93,19 @@ function* iterSync( } function readSync(rid, buffer) { - if (buffer.length === 0) { - return 0; - } - - const nread = ops.op_read_sync(rid, buffer); - + if (buffer.length === 0) return 0; + const nread = core.readSync(rid, buffer); return nread === 0 ? null : nread; } async function read(rid, buffer) { - if (buffer.length === 0) { - return 0; - } - + if (buffer.length === 0) return 0; const nread = await core.read(rid, buffer); - return nread === 0 ? null : nread; } function writeSync(rid, data) { - return ops.op_write_sync(rid, data); + return core.writeSync(rid, data); } function write(rid, data) { diff --git a/ext/io/lib.rs b/ext/io/lib.rs index 2f2e62c116..69f8c9da5e 100644 --- a/ext/io/lib.rs +++ b/ext/io/lib.rs @@ -78,7 +78,6 @@ pub static STDERR_HANDLE: Lazy = Lazy::new(|| { deno_core::extension!(deno_io, deps = [ deno_web ], - ops = [op_read_sync, op_write_sync], esm = [ "12_io.js" ], options = { stdio: Option, @@ -454,7 +453,7 @@ impl StdFileResource { } fn with_inner_and_metadata( - self: Rc, + &self, action: impl FnOnce( &mut StdFileResourceInner, &Arc>, @@ -471,10 +470,7 @@ impl StdFileResource { } } - async fn with_inner_blocking_task( - self: Rc, - action: F, - ) -> R + async fn with_inner_blocking_task(&self, action: F) -> R where F: FnOnce(&mut StdFileResourceInner) -> R + Send + 'static, { @@ -540,6 +536,14 @@ impl StdFileResource { .await } + fn read_byob_sync(&self, buf: &mut [u8]) -> Result { + self.with_inner_and_metadata(|inner, _| inner.read(buf).map_err(Into::into)) + } + + fn write_sync(&self, data: &[u8]) -> Result { + self.with_inner_and_metadata(|inner, _| inner.write_and_maybe_flush(data)) + } + fn with_resource( state: &mut OpState, rid: ResourceId, @@ -632,7 +636,7 @@ impl Resource for StdFileResource { Box::pin(async move { let vec = vec![0; limit]; let buf = BufMutView::from(vec); - let (nread, buf) = self.read_byob(buf).await?; + let (nread, buf) = StdFileResource::read_byob(self, buf).await?; let mut vec = buf.unwrap_vec(); if vec.len() != nread { vec.truncate(nread); @@ -645,17 +649,29 @@ impl Resource for StdFileResource { self: Rc, buf: deno_core::BufMutView, ) -> AsyncResult<(usize, deno_core::BufMutView)> { - Box::pin(self.read_byob(buf)) + Box::pin(StdFileResource::read_byob(self, buf)) } fn write( self: Rc, view: deno_core::BufView, ) -> AsyncResult { - Box::pin(self.write(view)) + Box::pin(StdFileResource::write(self, view)) } + fn write_all(self: Rc, view: deno_core::BufView) -> AsyncResult<()> { - Box::pin(self.write_all(view)) + Box::pin(StdFileResource::write_all(self, view)) + } + + fn write_sync(&self, data: &[u8]) -> Result { + StdFileResource::write_sync(self, data) + } + + fn read_byob_sync( + &self, + data: &mut [u8], + ) -> Result { + StdFileResource::read_byob_sync(self, data) } #[cfg(unix)] @@ -684,35 +700,3 @@ pub fn op_print( }) }) } - -#[op(fast)] -fn op_read_sync( - state: &mut OpState, - rid: u32, - buf: &mut [u8], -) -> Result { - StdFileResource::with_resource(state, rid, move |resource| { - resource.with_inner_and_metadata(|inner, _| { - inner - .read(buf) - .map(|n: usize| n as u32) - .map_err(AnyError::from) - }) - }) -} - -#[op(fast)] -fn op_write_sync( - state: &mut OpState, - rid: u32, - buf: &mut [u8], -) -> Result { - StdFileResource::with_resource(state, rid, move |resource| { - resource.with_inner_and_metadata(|inner, _| { - inner - .write_and_maybe_flush(buf) - .map(|nwritten: usize| nwritten as u32) - .map_err(AnyError::from) - }) - }) -}