summaryrefslogtreecommitdiff
path: root/runtime
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
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')
-rw-r--r--runtime/Cargo.toml1
-rw-r--r--runtime/js/30_fs.js20
-rw-r--r--runtime/js/90_deno_ns.js4
-rw-r--r--runtime/ops/fs.rs118
4 files changed, 143 insertions, 0 deletions
diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml
index 491516dbb..520509450 100644
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -65,6 +65,7 @@ atty = "0.2.14"
dlopen = "0.1.8"
encoding_rs = "0.8.28"
filetime = "0.2.14"
+fs3 = "0.5.0"
http = "0.2.4"
hyper = { version = "0.14.10", features = ["server", "stream", "http1", "http2", "runtime"] }
# TODO(lucacasonato): unlock when https://github.com/tkaitchuck/aHash/issues/95 is resolved
diff --git a/runtime/js/30_fs.js b/runtime/js/30_fs.js
index e45cda321..feb9f8f54 100644
--- a/runtime/js/30_fs.js
+++ b/runtime/js/30_fs.js
@@ -385,6 +385,22 @@
await core.opAsync("op_fsync_async", rid);
}
+ function flockSync(rid, exclusive) {
+ core.opSync("op_flock_sync", rid, exclusive === true);
+ }
+
+ async function flock(rid, exclusive) {
+ await core.opAsync("op_flock_async", rid, exclusive === true);
+ }
+
+ function funlockSync(rid) {
+ core.opSync("op_funlock_sync", rid);
+ }
+
+ async function funlock(rid) {
+ await core.opAsync("op_funlock_async", rid);
+ }
+
window.__bootstrap.fs = {
cwd,
chdir,
@@ -433,5 +449,9 @@
fdatasyncSync,
fsync,
fsyncSync,
+ flock,
+ flockSync,
+ funlock,
+ funlockSync,
};
})(this);
diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js
index 796361d7a..71c8bd0f0 100644
--- a/runtime/js/90_deno_ns.js
+++ b/runtime/js/90_deno_ns.js
@@ -136,5 +136,9 @@
createHttpClient: __bootstrap.fetch.createHttpClient,
http: __bootstrap.http,
dlopen: __bootstrap.ffi.dlopen,
+ flock: __bootstrap.fs.flock,
+ flockSync: __bootstrap.fs.flockSync,
+ funlock: __bootstrap.fs.funlock,
+ funlockSync: __bootstrap.fs.funlockSync,
};
})(this);
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>,