diff options
author | Tilman Roeder <dyed.green.info@gmail.com> | 2021-08-24 14:21:31 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-24 15:21:31 +0200 |
commit | 93d83a84dbe1f6ecf93b596f88bc85ba378fa986 (patch) | |
tree | 8f9165f29064b0eb6d34661577877ebc2a3e37b3 /runtime/ops/fs.rs | |
parent | 46e4ba38b2b1ccee8d3b4f04be1a2cc0b42cd52a (diff) |
feat(unstable): Add file locking APIs (#11746)
This commit adds following unstable APIs:
- Deno.flock()
- Deno.flockSync()
- Deno.funlock()
- Deno.funlockSync()
Diffstat (limited to 'runtime/ops/fs.rs')
-rw-r--r-- | runtime/ops/fs.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/runtime/ops/fs.rs b/runtime/ops/fs.rs index 419e41718..819f3f3ac 100644 --- a/runtime/ops/fs.rs +++ b/runtime/ops/fs.rs @@ -48,6 +48,10 @@ pub fn init() -> Extension { ("op_fsync_async", op_async(op_fsync_async)), ("op_fstat_sync", op_sync(op_fstat_sync)), ("op_fstat_async", op_async(op_fstat_async)), + ("op_flock_sync", op_sync(op_flock_sync)), + ("op_flock_async", op_async(op_flock_async)), + ("op_funlock_sync", op_sync(op_funlock_sync)), + ("op_funlock_async", op_async(op_funlock_async)), ("op_umask", op_sync(op_umask)), ("op_chdir", op_sync(op_chdir)), ("op_mkdir_sync", op_sync(op_mkdir_sync)), @@ -346,6 +350,120 @@ async fn op_fstat_async( Ok(get_stat(metadata)) } +fn op_flock_sync( + state: &mut OpState, + rid: ResourceId, + exclusive: bool, +) -> Result<(), AnyError> { + use fs3::FileExt; + super::check_unstable(state, "Deno.flockSync"); + + StdFileResource::with(state, rid, |r| match r { + Ok(std_file) => { + if exclusive { + std_file.lock_exclusive()?; + } else { + std_file.lock_shared()?; + } + Ok(()) + } + Err(_) => Err(type_error("cannot lock this type of resource".to_string())), + }) +} + +async fn op_flock_async( + state: Rc<RefCell<OpState>>, + rid: ResourceId, + exclusive: bool, +) -> Result<(), AnyError> { + use fs3::FileExt; + super::check_unstable2(&state, "Deno.flock"); + + let resource = state + .borrow_mut() + .resource_table + .get::<StdFileResource>(rid)?; + + if resource.fs_file.is_none() { + return Err(bad_resource_id()); + } + + let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap()) + .borrow_mut() + .await; + + let std_file = (*fs_file) + .0 + .as_mut() + .unwrap() + .try_clone() + .await? + .into_std() + .await; + tokio::task::spawn_blocking(move || -> Result<(), AnyError> { + if exclusive { + std_file.lock_exclusive()?; + } else { + std_file.lock_shared()?; + } + Ok(()) + }) + .await? +} + +fn op_funlock_sync( + state: &mut OpState, + rid: ResourceId, + _: (), +) -> Result<(), AnyError> { + use fs3::FileExt; + super::check_unstable(state, "Deno.funlockSync"); + + StdFileResource::with(state, rid, |r| match r { + Ok(std_file) => { + std_file.unlock()?; + Ok(()) + } + Err(_) => Err(type_error("cannot lock this type of resource".to_string())), + }) +} + +async fn op_funlock_async( + state: Rc<RefCell<OpState>>, + rid: ResourceId, + _: (), +) -> Result<(), AnyError> { + use fs3::FileExt; + super::check_unstable2(&state, "Deno.funlock"); + + let resource = state + .borrow_mut() + .resource_table + .get::<StdFileResource>(rid)?; + + if resource.fs_file.is_none() { + return Err(bad_resource_id()); + } + + let mut fs_file = RcRef::map(&resource, |r| r.fs_file.as_ref().unwrap()) + .borrow_mut() + .await; + + let std_file = (*fs_file) + .0 + .as_mut() + .unwrap() + .try_clone() + .await? + .into_std() + .await; + tokio::task::spawn_blocking(move || -> Result<(), AnyError> { + std_file.unlock()?; + Ok(()) + }) + .await? +} + fn op_umask( state: &mut OpState, mask: Option<u32>, |