Skip to content

Commit fc73036

Browse files
committed
io safety: update Unix explanation
1 parent 9adafa7 commit fc73036

File tree

1 file changed

+22
-9
lines changed
  • library/std/src/os/unix/io

1 file changed

+22
-9
lines changed

library/std/src/os/unix/io/mod.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
//! | Type | Analogous to |
1313
//! | ------------------ | ------------ |
1414
//! | [`RawFd`] | `*const _` |
15-
//! | [`BorrowedFd<'a>`] | `&'a _` |
16-
//! | [`OwnedFd`] | `Box<_>` |
15+
//! | [`BorrowedFd<'a>`] | `&'a Arc<_>` |
16+
//! | [`OwnedFd`] | `Arc<_>` |
1717
//!
1818
//! Like raw pointers, `RawFd` values are primitive values. And in new code,
1919
//! they should be considered unsafe to do I/O on (analogous to dereferencing
@@ -23,22 +23,33 @@
2323
//! either by adding `unsafe` to APIs that dereference `RawFd` values, or by
2424
//! using to `BorrowedFd` or `OwnedFd` instead.
2525
//!
26+
//! The use of `Arc` for borrowed/owned file descriptors may be surprising.
27+
//! Unix file descriptors are mere references to internal *file descriptions*,
28+
//! and the same file description can be referenced by multiple file descriptors
29+
//! (e.g. if `dup` is used). State such as the offset within the file is
30+
//! shared among all file descriptors that refer to the same file description,
31+
//! and the kernel internally does reference-counting to only close the underlying
32+
//! resource once all file descriptors referencing it are closed.
33+
//! That's why `Arc` (and not `Box`) is the closest Rust analogy to an "owned" file descriptor.
34+
//!
2635
//! Like references, `BorrowedFd` values are tied to a lifetime, to ensure
2736
//! that they don't outlive the resource they point to. These are safe to
2837
//! use. `BorrowedFd` values may be used in APIs which provide safe access to
2938
//! any system call except for:
3039
//!
3140
//! - `close`, because that would end the dynamic lifetime of the resource
32-
//! without ending the lifetime of the file descriptor.
41+
//! without ending the lifetime of the file descriptor. (Equivalently:
42+
//! an `&Arc<_>` cannot be `drop`ed.)
3343
//!
3444
//! - `dup2`/`dup3`, in the second argument, because this argument is
35-
//! closed and assigned a new resource, which may break the assumptions
45+
//! closed and assigned a new resource, which may break the assumptions of
3646
//! other code using that file descriptor.
3747
//!
3848
//! `BorrowedFd` values may be used in APIs which provide safe access to `dup`
39-
//! system calls, so types implementing `AsFd` or `From<OwnedFd>` should not
40-
//! assume they always have exclusive access to the underlying file
41-
//! description.
49+
//! system calls, so code working with `OwnedFd` cannot
50+
//! assume to have exclusive access to the underlying file
51+
//! description. (Equivalently: `&Arc` may be used in APIs that provide safe
52+
//! access to `clone`, so code working with an `Arc` cannot assume that the reference count is 1.)
4253
//!
4354
//! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the
4455
//! provided file descriptor in a manner similar to `dup` and does not require
@@ -52,8 +63,10 @@
5263
//! take full responsibility for ensuring that safe Rust code cannot evoke
5364
//! undefined behavior through it.
5465
//!
55-
//! Like boxes, `OwnedFd` values conceptually own the resource they point to,
56-
//! and free (close) it when they are dropped.
66+
//! Like `Arc`, `OwnedFd` values conceptually own one reference to the resource they point to,
67+
//! and decrement the reference count when they are dropped (by calling `close`).
68+
//! When the reference count reaches 0, the underlying file description will be freed
69+
//! by the kernel.
5770
//!
5871
//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
5972
//!

0 commit comments

Comments
 (0)