Skip to content

Commit b09746d

Browse files
authored
Merge pull request #245 from Berrysoft/dev/catch-unwind
feat(runtime): catch unwind in spawn*
2 parents 1f8497a + 84da23b commit b09746d

File tree

13 files changed

+93
-39
lines changed

13 files changed

+93
-39
lines changed

compio-fs/src/file.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{future::Future, io, mem::ManuallyDrop, path::Path};
1+
use std::{future::Future, io, mem::ManuallyDrop, panic::resume_unwind, path::Path};
22

33
use compio_buf::{BufResult, IntoInner, IoBuf, IoBufMut};
44
use compio_driver::{
@@ -74,7 +74,9 @@ impl File {
7474
#[cfg(windows)]
7575
pub async fn metadata(&self) -> io::Result<Metadata> {
7676
let file = self.inner.try_clone()?;
77-
compio_runtime::spawn_blocking(move || file.metadata().map(Metadata::from_std)).await
77+
compio_runtime::spawn_blocking(move || file.metadata().map(Metadata::from_std))
78+
.await
79+
.unwrap_or_else(|e| resume_unwind(e))
7880
}
7981

8082
/// Queries metadata about the underlying file.
@@ -89,7 +91,9 @@ impl File {
8991
#[cfg(windows)]
9092
pub async fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
9193
let file = self.inner.try_clone()?;
92-
compio_runtime::spawn_blocking(move || file.set_permissions(perm.0)).await
94+
compio_runtime::spawn_blocking(move || file.set_permissions(perm.0))
95+
.await
96+
.unwrap_or_else(|e| resume_unwind(e))
9397
}
9498

9599
/// Changes the permissions on the underlying file.
@@ -105,6 +109,7 @@ impl File {
105109
Ok(())
106110
})
107111
.await
112+
.unwrap_or_else(|e| resume_unwind(e))
108113
}
109114

110115
async fn sync_impl(&self, datasync: bool) -> io::Result<()> {

compio-fs/src/metadata/unix.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{
22
io,
33
os::unix::prelude::{FileTypeExt, MetadataExt, PermissionsExt},
4+
panic::resume_unwind,
45
path::Path,
56
time::{Duration, SystemTime},
67
};
@@ -33,6 +34,7 @@ pub async fn set_permissions(path: impl AsRef<Path>, perm: Permissions) -> io::R
3334
Ok(())
3435
})
3536
.await
37+
.unwrap_or_else(|e| resume_unwind(e))
3638
}
3739

3840
#[derive(Clone)]

compio-fs/src/metadata/windows.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
pub use std::fs::{FileType, Metadata, Permissions};
2-
use std::{io, path::Path};
2+
use std::{io, panic::resume_unwind, path::Path};
33

44
pub async fn metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
55
let path = path.as_ref().to_path_buf();
6-
compio_runtime::spawn_blocking(move || std::fs::metadata(path)).await
6+
compio_runtime::spawn_blocking(move || std::fs::metadata(path))
7+
.await
8+
.unwrap_or_else(|e| resume_unwind(e))
79
}
810

911
pub async fn symlink_metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
1012
let path = path.as_ref().to_path_buf();
11-
compio_runtime::spawn_blocking(move || std::fs::symlink_metadata(path)).await
13+
compio_runtime::spawn_blocking(move || std::fs::symlink_metadata(path))
14+
.await
15+
.unwrap_or_else(|e| resume_unwind(e))
1216
}
1317

1418
pub async fn set_permissions(path: impl AsRef<Path>, perm: Permissions) -> io::Result<()> {
1519
let path = path.as_ref().to_path_buf();
16-
compio_runtime::spawn_blocking(move || std::fs::set_permissions(path, perm)).await
20+
compio_runtime::spawn_blocking(move || std::fs::set_permissions(path, perm))
21+
.await
22+
.unwrap_or_else(|e| resume_unwind(e))
1723
}

compio-fs/src/open_options/windows.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{io, os::windows::fs::OpenOptionsExt, path::Path};
1+
use std::{io, os::windows::fs::OpenOptionsExt, panic::resume_unwind, path::Path};
22

33
use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_OVERLAPPED;
44

@@ -60,7 +60,9 @@ impl OpenOptions {
6060
let mut opt = self.opt.clone();
6161
opt.attributes(FILE_FLAG_OVERLAPPED);
6262
let p = p.as_ref().to_path_buf();
63-
let file = compio_runtime::spawn_blocking(move || opt.open(p)).await?;
63+
let file = compio_runtime::spawn_blocking(move || opt.open(p))
64+
.await
65+
.unwrap_or_else(|e| resume_unwind(e))?;
6466
File::new(file)
6567
}
6668
}

compio-fs/src/utils/windows.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,49 @@
1-
use std::{io, path::Path};
1+
use std::{io, panic::resume_unwind, path::Path};
22

33
pub async fn remove_file(path: impl AsRef<Path>) -> io::Result<()> {
44
let path = path.as_ref().to_path_buf();
5-
compio_runtime::spawn_blocking(move || std::fs::remove_file(path)).await
5+
compio_runtime::spawn_blocking(move || std::fs::remove_file(path))
6+
.await
7+
.unwrap_or_else(|e| resume_unwind(e))
68
}
79

810
pub async fn remove_dir(path: impl AsRef<Path>) -> io::Result<()> {
911
let path = path.as_ref().to_path_buf();
10-
compio_runtime::spawn_blocking(move || std::fs::remove_dir(path)).await
12+
compio_runtime::spawn_blocking(move || std::fs::remove_dir(path))
13+
.await
14+
.unwrap_or_else(|e| resume_unwind(e))
1115
}
1216

1317
pub async fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
1418
let from = from.as_ref().to_path_buf();
1519
let to = to.as_ref().to_path_buf();
16-
compio_runtime::spawn_blocking(move || std::fs::rename(from, to)).await
20+
compio_runtime::spawn_blocking(move || std::fs::rename(from, to))
21+
.await
22+
.unwrap_or_else(|e| resume_unwind(e))
1723
}
1824

1925
pub async fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
2026
let original = original.as_ref().to_path_buf();
2127
let link = link.as_ref().to_path_buf();
22-
compio_runtime::spawn_blocking(move || std::os::windows::fs::symlink_file(original, link)).await
28+
compio_runtime::spawn_blocking(move || std::os::windows::fs::symlink_file(original, link))
29+
.await
30+
.unwrap_or_else(|e| resume_unwind(e))
2331
}
2432

2533
pub async fn symlink_dir(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
2634
let original = original.as_ref().to_path_buf();
2735
let link = link.as_ref().to_path_buf();
28-
compio_runtime::spawn_blocking(move || std::os::windows::fs::symlink_dir(original, link)).await
36+
compio_runtime::spawn_blocking(move || std::os::windows::fs::symlink_dir(original, link))
37+
.await
38+
.unwrap_or_else(|e| resume_unwind(e))
2939
}
3040

3141
pub async fn hard_link(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
3242
let original = original.as_ref().to_path_buf();
3343
let link = link.as_ref().to_path_buf();
34-
compio_runtime::spawn_blocking(move || std::fs::hard_link(original, link)).await
44+
compio_runtime::spawn_blocking(move || std::fs::hard_link(original, link))
45+
.await
46+
.unwrap_or_else(|e| resume_unwind(e))
3547
}
3648

3749
pub struct DirBuilder;
@@ -43,6 +55,8 @@ impl DirBuilder {
4355

4456
pub async fn create(&self, path: &Path) -> io::Result<()> {
4557
let path = path.to_path_buf();
46-
compio_runtime::spawn_blocking(move || std::fs::create_dir(path)).await
58+
compio_runtime::spawn_blocking(move || std::fs::create_dir(path))
59+
.await
60+
.unwrap_or_else(|e| resume_unwind(e))
4761
}
4862
}

compio-net/src/resolve/unix.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use std::{
22
io,
33
net::{SocketAddr, ToSocketAddrs},
4+
panic::resume_unwind,
45
};
56

67
pub async fn resolve_sock_addrs(
78
host: &str,
89
port: u16,
910
) -> io::Result<std::vec::IntoIter<SocketAddr>> {
1011
let host = host.to_string();
11-
compio_runtime::spawn_blocking(move || (host, port).to_socket_addrs()).await
12+
compio_runtime::spawn_blocking(move || (host, port).to_socket_addrs())
13+
.await
14+
.unwrap_or_else(|e| resume_unwind(e))
1215
}

compio-net/src/socket.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ impl Socket {
3636

3737
#[cfg(windows)]
3838
pub async fn new(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Self> {
39-
let socket =
40-
compio_runtime::spawn_blocking(move || Socket2::new(domain, ty, protocol)).await?;
39+
use std::panic::resume_unwind;
40+
41+
let socket = compio_runtime::spawn_blocking(move || Socket2::new(domain, ty, protocol))
42+
.await
43+
.unwrap_or_else(|e| resume_unwind(e))?;
4144
Self::from_socket2(socket)
4245
}
4346

compio-net/tests/split.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::io::{Read, Write};
1+
use std::{
2+
io::{Read, Write},
3+
panic::resume_unwind,
4+
};
25

36
use compio_buf::BufResult;
47
use compio_io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
@@ -29,7 +32,7 @@ async fn tcp_split() {
2932
assert_eq!(&buf[..MSG.len()], MSG);
3033

3134
write_half.write_all(MSG).await.unwrap();
32-
handle.await;
35+
handle.await.unwrap_or_else(|e| resume_unwind(e));
3336
}
3437

3538
#[compio_macros::test]
@@ -55,7 +58,7 @@ async fn tcp_unsplit() {
5558

5659
read1.reunite(write1).expect("Reunite should succeed");
5760

58-
handle.await;
61+
handle.await.unwrap_or_else(|e| resume_unwind(e));
5962
}
6063

6164
#[compio_macros::test]

compio-net/tests/tcp_accept.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::panic::resume_unwind;
2+
13
use compio_net::{TcpListener, TcpStream, ToSocketAddrsAsync};
24

35
async fn test_impl(addr: impl ToSocketAddrsAsync) {
@@ -8,7 +10,7 @@ async fn test_impl(addr: impl ToSocketAddrsAsync) {
810
socket
911
});
1012
let cli = TcpStream::connect(&addr).await.unwrap();
11-
let srv = task.await;
13+
let srv = task.await.unwrap_or_else(|e| resume_unwind(e));
1214
assert_eq!(cli.local_addr().unwrap(), srv.peer_addr().unwrap());
1315
}
1416

compio-net/tests/tcp_connect.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::net::{IpAddr, SocketAddr};
1+
use std::{
2+
net::{IpAddr, SocketAddr},
3+
panic::resume_unwind,
4+
};
25

36
use compio_net::{TcpListener, TcpStream, ToSocketAddrsAsync};
47

@@ -17,7 +20,7 @@ async fn test_connect_ip_impl(
1720
});
1821

1922
let mine = TcpStream::connect(&addr).await.unwrap();
20-
let theirs = task.await;
23+
let theirs = task.await.unwrap_or_else(|e| resume_unwind(e));
2124

2225
assert_eq!(mine.local_addr().unwrap(), theirs.peer_addr().unwrap());
2326
assert_eq!(theirs.local_addr().unwrap(), mine.peer_addr().unwrap());

0 commit comments

Comments
 (0)