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

Commit 7c95bce

Browse files
Merge pull request #1036 from notgull/main
Implement I/O-safe traits on types
2 parents 1855e85 + c177103 commit 7c95bce

File tree

15 files changed

+371
-6
lines changed

15 files changed

+371
-6
lines changed

‎.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,21 @@ jobs:
108108
with:
109109
command: check
110110
args: --all --features tokio02
111+
112+
check_io_safety_feature:
113+
name: Check io_safety feature
114+
runs-on: ${{ matrix.os }}
115+
strategy:
116+
matrix:
117+
os: [ubuntu-latest, windows-latest]
118+
steps:
119+
- uses: actions/checkout@v3
120+
- name: check io_safety
121+
uses: actions-rs/cargo@v1
122+
with:
123+
command: check
124+
args: --all --features io_safety
125+
111126

112127
cross:
113128
name: Cross compile

‎Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ alloc = [
5858
tokio1 = ["async-global-executor/tokio"]
5959
tokio02 = ["async-global-executor/tokio02"]
6060
tokio03 = ["async-global-executor/tokio03"]
61+
io_safety = []
6162

6263
[dependencies]
6364
async-attributes = { version = "1.1.1", optional = true }

‎src/fs/file.rs

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use crate::prelude::*;
1515
use crate::task::{spawn_blocking, Context, Poll, Waker};
1616
use crate::utils::Context as _;
1717

18+
const ARC_TRY_UNWRAP_EXPECT: &str = "cannot acquire ownership of the file handle after drop";
19+
1820
/// An open file on the filesystem.
1921
///
2022
/// Depending on what options the file was opened with, this type can be used for reading and/or
@@ -415,6 +417,15 @@ impl From<std::fs::File> for File {
415417
cfg_unix! {
416418
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
417419

420+
impl File {
421+
fn into_std_file(self) -> std::fs::File {
422+
let file = self.file.clone();
423+
drop(self);
424+
Arc::try_unwrap(file)
425+
.expect(ARC_TRY_UNWRAP_EXPECT)
426+
}
427+
}
428+
418429
impl AsRawFd for File {
419430
fn as_raw_fd(&self) -> RawFd {
420431
self.file.as_raw_fd()
@@ -429,11 +440,29 @@ cfg_unix! {
429440

430441
impl IntoRawFd for File {
431442
fn into_raw_fd(self) -> RawFd {
432-
let file = self.file.clone();
433-
drop(self);
434-
Arc::try_unwrap(file)
435-
.expect("cannot acquire ownership of the file handle after drop")
436-
.into_raw_fd()
443+
self.into_std_file().into_raw_fd()
444+
}
445+
}
446+
447+
cfg_io_safety! {
448+
use crate::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
449+
450+
impl AsFd for File {
451+
fn as_fd(&self) -> BorrowedFd<'_> {
452+
self.file.as_fd()
453+
}
454+
}
455+
456+
impl From<OwnedFd> for File {
457+
fn from(fd: OwnedFd) -> Self {
458+
std::fs::File::from(fd).into()
459+
}
460+
}
461+
462+
impl From<File> for OwnedFd {
463+
fn from(val: File) -> OwnedFd {
464+
self.into_std_file().into()
465+
}
437466
}
438467
}
439468
}
@@ -458,10 +487,36 @@ cfg_windows! {
458487
let file = self.file.clone();
459488
drop(self);
460489
Arc::try_unwrap(file)
461-
.expect("cannot acquire ownership of the file handle after drop")
490+
.expect(ARC_TRY_UNWRAP_EXPECT)
462491
.into_raw_handle()
463492
}
464493
}
494+
495+
cfg_io_safety! {
496+
use crate::os::windows::io::{AsHandle, BorrowedHandle, OwnedHandle};
497+
498+
impl AsHandle for File {
499+
fn as_handle(&self) -> BorrowedHandle<'_> {
500+
self.file.as_handle()
501+
}
502+
}
503+
504+
impl From<OwnedHandle> for File {
505+
fn from(handle: OwnedHandle) -> Self {
506+
std::fs::File::from(handle).into()
507+
}
508+
}
509+
510+
impl From<File> for OwnedHandle {
511+
fn from(val: File) -> OwnedHandle {
512+
let file = val.file.clone();
513+
drop(val);
514+
Arc::try_unwrap(file)
515+
.expect(ARC_TRY_UNWRAP_EXPECT)
516+
.into()
517+
}
518+
}
519+
}
465520
}
466521

467522
/// An async mutex with non-borrowing lock guards.

‎src/io/stderr.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@ cfg_unix! {
180180
std::io::stderr().as_raw_fd()
181181
}
182182
}
183+
184+
cfg_io_safety! {
185+
use crate::os::unix::io::{AsFd, BorrowedFd};
186+
187+
impl AsFd for Stderr {
188+
fn as_fd(&self) -> BorrowedFd<'_> {
189+
std::io::stderr().as_fd()
190+
}
191+
}
192+
}
183193
}
184194

185195
cfg_windows! {
@@ -190,4 +200,14 @@ cfg_windows! {
190200
std::io::stderr().as_raw_handle()
191201
}
192202
}
203+
204+
cfg_io_safety! {
205+
use crate::os::unix::io::{AsHandle, BorrowedHandle};
206+
207+
impl AsHandle for Stderr {
208+
fn as_handle(&self) -> BorrowedHandle<'_> {
209+
std::io::stderr().as_handle()
210+
}
211+
}
212+
}
193213
}

‎src/io/stdin.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,16 @@ cfg_unix! {
206206
std::io::stdin().as_raw_fd()
207207
}
208208
}
209+
210+
cfg_io_safety! {
211+
use crate::os::unix::io::{AsFd, BorrowedFd};
212+
213+
impl AsFd for Stderr {
214+
fn as_fd(&self) -> BorrowedFd<'_> {
215+
std::io::stdin().as_fd()
216+
}
217+
}
218+
}
209219
}
210220

211221
cfg_windows! {
@@ -216,4 +226,14 @@ cfg_windows! {
216226
std::io::stdin().as_raw_handle()
217227
}
218228
}
229+
230+
cfg_io_safety! {
231+
use crate::os::unix::io::{AsFd, BorrowedFd};
232+
233+
impl AsFd for Stdin {
234+
fn as_fd(&self) -> BorrowedFd<'_> {
235+
std::io::stdin().as_fd()
236+
}
237+
}
238+
}
219239
}

‎src/io/stdout.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@ cfg_unix! {
180180
std::io::stdout().as_raw_fd()
181181
}
182182
}
183+
184+
cfg_io_safety! {
185+
use crate::os::unix::io::{AsFd, BorrowedFd};
186+
187+
impl AsFd for Stdout {
188+
fn as_fd(&self) -> BorrowedFd<'_> {
189+
std::io::stdout().as_fd()
190+
}
191+
}
192+
}
183193
}
184194

185195
cfg_windows! {
@@ -190,4 +200,14 @@ cfg_windows! {
190200
std::io::stdout().as_raw_handle()
191201
}
192202
}
203+
204+
cfg_io_safety! {
205+
use crate::os::unix::io::{AsHandle, BorrowedHandle};
206+
207+
impl AsHandle for Stdout {
208+
fn as_handle(&self) -> BorrowedHandle<'_> {
209+
std::io::stdout().as_handle()
210+
}
211+
}
212+
}
193213
}

‎src/net/tcp/listener.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,28 @@ cfg_unix! {
282282
self.watcher.into_inner().unwrap().into_raw_fd()
283283
}
284284
}
285+
286+
cfg_io_safety! {
287+
use crate::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
288+
289+
impl AsFd for TcpListener {
290+
fn as_fd(&self) -> BorrowedFd<'_> {
291+
self.watcher.get_ref().as_fd()
292+
}
293+
}
294+
295+
impl From<OwnedFd> for TcpListener {
296+
fn from(fd: OwnedFd) -> TcpListener {
297+
std::net::TcpListener::from(fd).into()
298+
}
299+
}
300+
301+
impl From<TcpListener> for OwnedFd {
302+
fn from(listener: TcpListener) -> OwnedFd {
303+
listener.watcher.into_inner().unwrap().into()
304+
}
305+
}
306+
}
285307
}
286308

287309
cfg_windows! {
@@ -306,4 +328,26 @@ cfg_windows! {
306328
self.watcher.into_inner().unwrap().into_raw_socket()
307329
}
308330
}
331+
332+
cfg_io_safety! {
333+
use crate::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
334+
335+
impl AsSocket for TcpListener {
336+
fn as_socket(&self) -> BorrowedSocket<'_> {
337+
self.watcher.get_ref().as_socket()
338+
}
339+
}
340+
341+
impl From<OwnedSocket> for TcpListener {
342+
fn from(fd: OwnedSocket) -> TcpListener {
343+
std::net::TcpListener::from(fd).into()
344+
}
345+
}
346+
347+
impl From<TcpListener> for OwnedSocket {
348+
fn from(listener: TcpListener) -> OwnedSocket {
349+
listener.watcher.into_inner().unwrap().into()
350+
}
351+
}
352+
}
309353
}

‎src/net/tcp/stream.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,28 @@ cfg_unix! {
416416
self.as_raw_fd()
417417
}
418418
}
419+
420+
cfg_io_safety! {
421+
use crate::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
422+
423+
impl AsFd for TcpStream {
424+
fn as_fd(&self) -> BorrowedFd<'_> {
425+
self.watcher.get_ref().as_fd()
426+
}
427+
}
428+
429+
impl From<OwnedFd> for TcpStream {
430+
fn from(fd: OwnedFd) -> TcpStream {
431+
std::net::TcpStream::from(fd).into()
432+
}
433+
}
434+
435+
impl From<TcpStream> for OwnedFd {
436+
fn from(stream: TcpStream) -> OwnedFd {
437+
stream.watcher.into_inner().unwrap().into()
438+
}
439+
}
440+
}
419441
}
420442

421443
cfg_windows! {
@@ -443,4 +465,26 @@ cfg_windows! {
443465
self.as_raw_socket()
444466
}
445467
}
468+
469+
cfg_io_safety! {
470+
use crate::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
471+
472+
impl AsSocket for TcpStream {
473+
fn as_socket(&self) -> BorrowedSocket<'_> {
474+
self.watcher.get_ref().as_socket()
475+
}
476+
}
477+
478+
impl From<OwnedSocket> for TcpStream {
479+
fn from(fd: OwnedSocket) -> TcpStream {
480+
std::net::TcpListener::from(fd).into()
481+
}
482+
}
483+
484+
impl From<TcpStream> for OwnedSocket {
485+
fn from(stream: TcpStream) -> OwnedSocket {
486+
stream.watcher.into_inner().unwrap().into()
487+
}
488+
}
489+
}
446490
}

‎src/net/udp/mod.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,28 @@ cfg_unix! {
562562
self.watcher.into_inner().unwrap().into_raw_fd()
563563
}
564564
}
565+
566+
cfg_io_safety! {
567+
use crate::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
568+
569+
impl AsFd for UdpSocket {
570+
fn as_fd(&self) -> BorrowedFd<'_> {
571+
self.watcher.get_ref().as_fd()
572+
}
573+
}
574+
575+
impl From<OwnedFd> for UdpSocket {
576+
fn from(fd: OwnedFd) -> UdpSocket {
577+
std::net::TcpStream::from(fd).into()
578+
}
579+
}
580+
581+
impl From<UdpSocket> for OwnedFd {
582+
fn from(stream: UdpSocket) -> OwnedFd {
583+
stream.watcher.into_inner().unwrap().into()
584+
}
585+
}
586+
}
565587
}
566588

567589
cfg_windows! {
@@ -586,4 +608,26 @@ cfg_windows! {
586608
self.watcher.into_inner().unwrap().into_raw_socket()
587609
}
588610
}
611+
612+
cfg_io_safety! {
613+
use crate::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
614+
615+
impl AsSocket for UdpSocket {
616+
fn as_socket(&self) -> BorrowedSocket<'_> {
617+
self.watcher.get_ref().as_socket()
618+
}
619+
}
620+
621+
impl From<OwnedSocket> for UdpSocket {
622+
fn from(fd: OwnedSocket) -> UdpSocket {
623+
std::net::TcpListener::from(fd).into()
624+
}
625+
}
626+
627+
impl From<UdpSocket> for OwnedSocket {
628+
fn from(stream: UdpSocket) -> OwnedSocket {
629+
stream.watcher.into_inner().unwrap().into()
630+
}
631+
}
632+
}
589633
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /