summaryrefslogtreecommitdiff
path: root/runtime/ops/fs.rs
diff options
context:
space:
mode:
authorTilman Roeder <dyed.green.info@gmail.com>2021-08-24 14:21:31 +0100
committerGitHub <noreply@github.com>2021-08-24 15:21:31 +0200
commit93d83a84dbe1f6ecf93b596f88bc85ba378fa986 (patch)
tree8f9165f29064b0eb6d34661577877ebc2a3e37b3 /runtime/ops/fs.rs
parent46e4ba38b2b1ccee8d3b4f04be1a2cc0b42cd52a (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.rs118
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>,