fs4/windows/
async_impl.rs1macro_rules! allocate_size {
2 ($file: ty) => {
3 pub async fn allocated_size(file: &$file) -> Result<u64> {
4 unsafe {
5 let mut info: FILE_STANDARD_INFO = mem::zeroed();
6
7 let ret = GetFileInformationByHandleEx(
8 file.as_raw_handle() as HANDLE,
9 FileStandardInfo,
10 &mut info as *mut _ as *mut _,
11 mem::size_of::<FILE_STANDARD_INFO>() as u32,
12 );
13
14 if ret == 0 {
15 Err(Error::last_os_error())
16 } else {
17 Ok(info.AllocationSize as u64)
18 }
19 }
20 }
21 };
22}
23
24macro_rules! allocate {
25 ($file: ty) => {
26 pub async fn allocate(file: &$file, len: u64) -> Result<()> {
27 if allocated_size(file).await? < len {
28 unsafe {
29 let mut info: FILE_ALLOCATION_INFO = mem::zeroed();
30 info.AllocationSize = len as i64;
31 let ret = SetFileInformationByHandle(
32 file.as_raw_handle() as HANDLE,
33 FileAllocationInfo,
34 &mut info as *mut _ as *mut _,
35 mem::size_of::<FILE_ALLOCATION_INFO>() as u32,
36 );
37 if ret == 0 {
38 return Err(Error::last_os_error());
39 }
40 }
41 }
42 if file.metadata().await?.len() < len {
43 file.set_len(len).await
44 } else {
45 Ok(())
46 }
47 }
48 };
49}
50
51macro_rules! test_mod {
52 ($annotation:meta, $($use_stmt:item)*) => {
53 #[cfg(test)]
54 mod test {
55 extern crate tempfile;
56
57 $(
58 $use_stmt
59 )*
60
61 #[$annotation]
64 async fn lock_non_reentrant() {
65 let tempdir = tempfile::TempDir::with_prefix("fs4").unwrap();
66 let path = tempdir.path().join("fs4");
67 let file = fs::OpenOptions::new()
68 .read(true)
69 .write(true)
70 .create(true)
71 .open(&path)
72 .await
73 .unwrap();
74
75 file.lock_exclusive().unwrap();
77 assert_eq!(
78 file.try_lock_exclusive().unwrap(),
79 false
80 );
81 file.unlock().unwrap();
82
83 file.lock_shared().unwrap();
85 assert_eq!(
86 file.try_lock_exclusive().unwrap(),
87 false
88 );
89 }
90
91 #[$annotation]
94 async fn lock_layering() {
95 let tempdir = tempfile::TempDir::with_prefix("fs4").unwrap();
96 let path = tempdir.path().join("fs4");
97 let file = fs::OpenOptions::new()
98 .read(true)
99 .write(true)
100 .create(true)
101 .open(&path)
102 .await
103 .unwrap();
104
105 file.lock_exclusive().unwrap();
107 file.lock_shared().unwrap();
108 file.lock_shared().unwrap();
109 assert_eq!(
110 file.try_lock_exclusive().unwrap(),
111 false,
112 "the first try lock exclusive",
113 );
114
115 file.unlock().unwrap();
117 assert_eq!(
118 file.try_lock_exclusive().unwrap(),
119 false,
120 "pop the first shared lock",
121 );
122
123 file.unlock().unwrap();
125 assert_eq!(
126 file.try_lock_exclusive().unwrap(),
127 false,
128 "pop the second shared lock",
129 );
130
131 file.unlock().unwrap();
133 file.lock_exclusive().unwrap();
134 }
135
136 #[$annotation]
138 async fn lock_layering_cleanup() {
139 let tempdir = tempfile::TempDir::with_prefix("fs4").unwrap();
140 let path = tempdir.path().join("fs4");
141 let file1 = fs::OpenOptions::new()
142 .read(true)
143 .write(true)
144 .create(true)
145 .open(&path)
146 .await
147 .unwrap();
148 let file2 = fs::OpenOptions::new()
149 .read(true)
150 .write(true)
151 .create(true)
152 .open(&path)
153 .await
154 .unwrap();
155
156 file1.lock_shared().unwrap();
158 assert_eq!(
159 file2.try_lock_exclusive().unwrap(),
160 false
161 );
162
163 drop(file1);
164 file2.lock_exclusive().unwrap();
165 }
166 }
167 };
168}
169
170cfg_async_std! {
171 pub(crate) mod async_std_impl;
172}
173
174cfg_fs_err2_tokio! {
175 pub(crate) mod fs_err2_tokio_impl;
176}
177
178cfg_fs_err3_tokio! {
179 pub(crate) mod fs_err3_tokio_impl;
180}
181
182cfg_smol! {
183 pub(crate) mod smol_impl;
184}
185
186cfg_tokio! {
187 pub(crate) mod tokio_impl;
188}