Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromdanburkert/fs2-rs

Commit58cc3f2

Browse files
authored
0.10.0 (#27)
* Add `*_async` APIs
1 parenta96c0e4 commit58cc3f2

File tree

7 files changed

+218
-8
lines changed

7 files changed

+218
-8
lines changed

‎.github/FUNDING.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
github:al8n
2+
patreon:al8n
3+
ko_fi:al8n9434

‎.github/dependabot.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version:2
2+
updates:
3+
-package-ecosystem:"cargo"
4+
directory:"/"
5+
schedule:
6+
interval:"weekly"
7+
open-pull-requests-limit:50
8+
9+
-package-ecosystem:"github-actions"
10+
directory:"/"
11+
schedule:
12+
# Check for updates to GitHub Actions every weekday
13+
interval:"daily"

‎.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,30 @@ jobs:
9696
-name:test all features
9797
# Run sequentially to avoid race condition around file system size
9898
run:cargo test --all-features -- --test-threads 1
99+
docs:
100+
name:docs
101+
runs-on:ubuntu-latest
102+
steps:
103+
-uses:actions/checkout@v4
104+
-name:Cache cargo build and registry
105+
uses:actions/cache@v4
106+
with:
107+
path:|
108+
~/.cargo/registry
109+
~/.cargo/git
110+
target
111+
key:ubuntu-latest-docs-${{ hashFiles('**/Cargo.lock') }}
112+
restore-keys:|
113+
ubuntu-latest-docs-
114+
-uses:actions-rs/toolchain@v1
115+
with:
116+
toolchain:${{ env.nightly }}
117+
override:true
118+
-name:"doc --lib --all-features"
119+
run:cargo doc --lib --no-deps --all-features
120+
env:
121+
RUSTFLAGS:--cfg docsrs
122+
RUSTDOCFLAGS:--cfg docsrs -Dwarnings
99123

100124
coverage:
101125
name:cargo tarpaulin

‎Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name ="fs4"
33
# NB: When modifying, also modify html_root_url in lib.rs
4-
version ="0.9.1"
4+
version ="0.10.0"
55
rust-version ="1.75.0"
66
authors = ["Dan Burkert <dan@danburkert.com>","Al Liu <scygliu1@gmail.com>"]
77
license ="MIT OR Apache-2.0"

‎README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,37 @@ This is a fork of the [fs2-rs](https://github.com/danburkert/fs2-rs) crate, the
2323
- std
2424
```toml
2525
[dependencies]
26-
fs4 = {version ="0.9",features = ["sync"] }
26+
fs4 = {version ="0.10",features = ["sync"] }
2727
```
2828

2929
- [async-std runtime](https://crates.io/crates/async-std)
3030
```toml
3131
[dependencies]
32-
fs4 = {version ="0.9",features = ["async-std"] }
32+
fs4 = {version ="0.10",features = ["async-std"] }
3333
```
3434

3535
- [fs-err](https://crates.io/crates/fs-err)
3636
```toml
3737
[dependencies]
38-
fs4 = {version ="0.9",features = ["fs-err"] }
38+
fs4 = {version ="0.10",features = ["fs-err"] }
3939
```
4040

4141
- [fs-err-tokio](https://crates.io/crates/fs-err)
4242
```toml
4343
[dependencies]
44-
fs4 = {version ="0.9",features = ["fs-err-tokio"] }
44+
fs4 = {version ="0.10",features = ["fs-err-tokio"] }
4545
```
4646

4747
- [smol runtime](https://crates.io/crates/smol)
4848
```toml
4949
[dependencies]
50-
fs4 = {version ="0.9",features = ["smol"] }
50+
fs4 = {version ="0.10",features = ["smol"] }
5151
```
5252

5353
- [tokio runtime](https://crates.io/crates/tokio)
5454
```toml
5555
[dependencies]
56-
fs4 = {version ="0.9",features = ["tokio"] }
56+
fs4 = {version ="0.10",features = ["tokio"] }
5757
```
5858

5959
## Features

‎src/file_ext/async_impl.rs

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,54 @@ macro_rules! async_file_ext {
4242
/// locked exclusively.
4343
fn lock_shared(&self) ->Result<()>;
4444

45+
/// Locks the file for exclusive usage, blocking if the file is currently
46+
/// locked exclusively.
47+
///
48+
/// **Note:** This method is not really "async", the underlying system call is still blocking.
49+
/// Having this method as async is just for convenience when using it in async runtime.
50+
fn lock_shared_async(&self) ->impl core::future::Future<Output =Result<()>>;
51+
4552
/// Locks the file for exclusive usage, blocking if the file is currently
4653
/// locked.
4754
fn lock_exclusive(&self) ->Result<()>;
4855

56+
/// Locks the file for exclusive usage, blocking if the file is currently
57+
/// locked.
58+
///
59+
/// **Note:** This method is not really "async", the underlying system call is still blocking.
60+
/// Having this method as async is just for convenience when using it in async runtime.
61+
fn lock_exclusive_async(&self) ->impl core::future::Future<Output =Result<()>>;
62+
4963
/// Locks the file for shared usage, or returns an error if the file is
5064
/// currently locked (see `lock_contended_error`).
5165
fn try_lock_shared(&self) ->Result<()>;
5266

67+
/// Locks the file for shared usage, or returns an error if the file is
68+
/// currently locked (see `lock_contended_error`).
69+
///
70+
/// **Note:** This method is not really "async", the underlying system call is still blocking.
71+
/// Having this method as async is just for convenience when using it in async runtime.
72+
fn try_lock_shared_async(&self) ->impl core::future::Future<Output =Result<()>>;
73+
5374
/// Locks the file for exclusive usage, or returns an error if the file is
5475
/// currently locked (see `lock_contended_error`).
5576
fn try_lock_exclusive(&self) ->Result<()>;
5677

78+
/// Locks the file for exclusive usage, or returns an error if the file is
79+
/// currently locked (see `lock_contended_error`).
80+
///
81+
/// **Note:** This method is not really "async", the underlying system call is still blocking.
82+
/// Having this method as async is just for convenience when using it in async runtime.
83+
fn try_lock_exclusive_async(&self) ->impl core::future::Future<Output =Result<()>>;
84+
5785
/// Unlocks the file.
5886
fn unlock(&self) ->Result<()>;
87+
88+
/// Unlocks the file.
89+
///
90+
/// **Note:** This method is not really "async", the underlying system call is still blocking.
91+
/// Having this method as async is just for convenience when using it in async runtime.
92+
fn unlock_async(&self) ->impl core::future::Future<Output =Result<()>>;
5993
}
6094

6195
implAsyncFileExtfor $file{
@@ -68,18 +102,42 @@ macro_rules! async_file_ext {
68102
fn lock_shared(&self) ->Result<()>{
69103
sys::lock_shared(self)
70104
}
105+
106+
asyncfn lock_shared_async(&self) ->Result<()>{
107+
sys::lock_shared(self)
108+
}
109+
71110
fn lock_exclusive(&self) ->Result<()>{
72111
sys::lock_exclusive(self)
73112
}
113+
114+
asyncfn lock_exclusive_async(&self) ->Result<()>{
115+
sys::lock_exclusive(self)
116+
}
117+
74118
fn try_lock_shared(&self) ->Result<()>{
75119
sys::try_lock_shared(self)
76120
}
121+
122+
asyncfn try_lock_shared_async(&self) ->Result<()>{
123+
sys::try_lock_shared(self)
124+
}
125+
77126
fn try_lock_exclusive(&self) ->Result<()>{
78127
sys::try_lock_exclusive(self)
79128
}
129+
130+
asyncfn try_lock_exclusive_async(&self) ->Result<()>{
131+
sys::try_lock_exclusive(self)
132+
}
133+
80134
fn unlock(&self) ->Result<()>{
81135
sys::unlock(self)
82136
}
137+
138+
asyncfn unlock_async(&self) ->Result<()>{
139+
sys::unlock(self)
140+
}
83141
}
84142
}
85143
}
@@ -144,6 +202,51 @@ macro_rules! test_mod {
144202
file3.lock_exclusive().unwrap();
145203
}
146204

205+
/// Tests shared file lock operations.
206+
#[$annotation]
207+
asyncfn lock_shared_async(){
208+
let tempdir = tempdir::TempDir::new("fs4").unwrap();
209+
let path = tempdir.path().join("fs4");
210+
let file1 = fs::OpenOptions::new()
211+
.read(true)
212+
.write(true)
213+
.create(true)
214+
.open(&path)
215+
.await
216+
.unwrap();
217+
let file2 = fs::OpenOptions::new()
218+
.read(true)
219+
.write(true)
220+
.create(true)
221+
.open(&path)
222+
.await
223+
.unwrap();
224+
let file3 = fs::OpenOptions::new()
225+
.read(true)
226+
.write(true)
227+
.create(true)
228+
.open(&path)
229+
.await
230+
.unwrap();
231+
232+
// Concurrent shared access is OK, but not shared and exclusive.
233+
file1.lock_shared_async().await.unwrap();
234+
file2.lock_shared_async().await.unwrap();
235+
assert_eq!(
236+
file3.try_lock_exclusive_async().await.unwrap_err().kind(),
237+
lock_contended_error().kind()
238+
);
239+
file1.unlock_async().await.unwrap();
240+
assert_eq!(
241+
file3.try_lock_exclusive_async().await.unwrap_err().kind(),
242+
lock_contended_error().kind()
243+
);
244+
245+
// Once all shared file locks are dropped, an exclusive lock may be created;
246+
file2.unlock_async().await.unwrap();
247+
file3.lock_exclusive_async().await.unwrap();
248+
}
249+
147250
/// Tests exclusive file lock operations.
148251
#[$annotation]
149252
asyncfn lock_exclusive(){
@@ -180,6 +283,42 @@ macro_rules! test_mod {
180283
file2.lock_exclusive().unwrap();
181284
}
182285

286+
/// Tests exclusive file lock operations.
287+
#[$annotation]
288+
asyncfn lock_exclusive_async(){
289+
let tempdir = tempdir::TempDir::new("fs4").unwrap();
290+
let path = tempdir.path().join("fs4");
291+
let file1 = fs::OpenOptions::new()
292+
.read(true)
293+
.write(true)
294+
.create(true)
295+
.open(&path)
296+
.await
297+
.unwrap();
298+
let file2 = fs::OpenOptions::new()
299+
.read(true)
300+
.write(true)
301+
.create(true)
302+
.open(&path)
303+
.await
304+
.unwrap();
305+
306+
// No other access is possible once an exclusive lock is created.
307+
file1.lock_exclusive_async().await.unwrap();
308+
assert_eq!(
309+
file2.try_lock_exclusive_async().await.unwrap_err().kind(),
310+
lock_contended_error().kind()
311+
);
312+
assert_eq!(
313+
file2.try_lock_shared_async().await.unwrap_err().kind(),
314+
lock_contended_error().kind()
315+
);
316+
317+
// Once the exclusive lock is dropped, the second file is able to create a lock.
318+
file1.unlock_async().await.unwrap();
319+
file2.lock_exclusive_async().await.unwrap();
320+
}
321+
183322
/// Tests that a lock is released after the file that owns it is dropped.
184323
#[$annotation]
185324
asyncfn lock_cleanup(){
@@ -211,6 +350,37 @@ macro_rules! test_mod {
211350
file2.lock_shared().unwrap();
212351
}
213352

353+
/// Tests that a lock is released after the file that owns it is dropped.
354+
#[$annotation]
355+
asyncfn lock_cleanup_async(){
356+
let tempdir = tempdir::TempDir::new("fs4").unwrap();
357+
let path = tempdir.path().join("fs4");
358+
let file1 = fs::OpenOptions::new()
359+
.read(true)
360+
.write(true)
361+
.create(true)
362+
.open(&path)
363+
.await
364+
.unwrap();
365+
let file2 = fs::OpenOptions::new()
366+
.read(true)
367+
.write(true)
368+
.create(true)
369+
.open(&path)
370+
.await
371+
.unwrap();
372+
373+
file1.lock_exclusive_async().await.unwrap();
374+
assert_eq!(
375+
file2.try_lock_shared_async().await.unwrap_err().kind(),
376+
lock_contended_error().kind()
377+
);
378+
379+
// Drop file1; the lock should be released.
380+
drop(file1);
381+
file2.lock_shared_async().await.unwrap();
382+
}
383+
214384
/// Tests file allocation.
215385
#[$annotation]
216386
asyncfn allocate(){

‎src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Extended utilities for working with files and filesystems in Rust.
2-
#![doc(html_root_url ="https://docs.rs/fs4/0.9.1")]
2+
#![doc(html_root_url ="https://docs.rs/fs4/0.10.0")]
33
#![cfg_attr(test, feature(test))]
44
#![cfg_attr(docsrs, feature(doc_cfg))]
55
#![cfg_attr(docsrs, allow(unused_attributes))]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp