Rollup merge of #124412 - RalfJung:io-safety, r=Amanieu
io safety: update Unix explanation to use `Arc` Fixes https://github.com/rust-lang/rust/issues/124384 Cc ```@jsgf```
This commit is contained in:
commit
9ab5cfd91e
2 changed files with 22 additions and 11 deletions
|
@ -266,7 +266,7 @@
|
||||||
//! its file descriptors with no operations being performed by any other part of the program.
|
//! its file descriptors with no operations being performed by any other part of the program.
|
||||||
//!
|
//!
|
||||||
//! Note that exclusive ownership of a file descriptor does *not* imply exclusive ownership of the
|
//! Note that exclusive ownership of a file descriptor does *not* imply exclusive ownership of the
|
||||||
//! underlying kernel object that the file descriptor references (also called "file description" on
|
//! underlying kernel object that the file descriptor references (also called "open file description" on
|
||||||
//! some operating systems). File descriptors basically work like [`Arc`]: when you receive an owned
|
//! some operating systems). File descriptors basically work like [`Arc`]: when you receive an owned
|
||||||
//! file descriptor, you cannot know whether there are any other file descriptors that reference the
|
//! file descriptor, you cannot know whether there are any other file descriptors that reference the
|
||||||
//! same kernel object. However, when you create a new kernel object, you know that you are holding
|
//! same kernel object. However, when you create a new kernel object, you know that you are holding
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
//! | Type | Analogous to |
|
//! | Type | Analogous to |
|
||||||
//! | ------------------ | ------------ |
|
//! | ------------------ | ------------ |
|
||||||
//! | [`RawFd`] | `*const _` |
|
//! | [`RawFd`] | `*const _` |
|
||||||
//! | [`BorrowedFd<'a>`] | `&'a _` |
|
//! | [`BorrowedFd<'a>`] | `&'a Arc<_>` |
|
||||||
//! | [`OwnedFd`] | `Box<_>` |
|
//! | [`OwnedFd`] | `Arc<_>` |
|
||||||
//!
|
//!
|
||||||
//! Like raw pointers, `RawFd` values are primitive values. And in new code,
|
//! Like raw pointers, `RawFd` values are primitive values. And in new code,
|
||||||
//! they should be considered unsafe to do I/O on (analogous to dereferencing
|
//! they should be considered unsafe to do I/O on (analogous to dereferencing
|
||||||
|
@ -23,22 +23,31 @@
|
||||||
//! either by adding `unsafe` to APIs that dereference `RawFd` values, or by
|
//! either by adding `unsafe` to APIs that dereference `RawFd` values, or by
|
||||||
//! using to `BorrowedFd` or `OwnedFd` instead.
|
//! using to `BorrowedFd` or `OwnedFd` instead.
|
||||||
//!
|
//!
|
||||||
|
//! The use of `Arc` for borrowed/owned file descriptors may be surprising. Unix file descriptors
|
||||||
|
//! are mere references to internal kernel objects called "open file descriptions", and the same
|
||||||
|
//! open file description can be referenced by multiple file descriptors (e.g. if `dup` is used).
|
||||||
|
//! State such as the offset within the file is shared among all file descriptors that refer to the
|
||||||
|
//! same open file description, and the kernel internally does reference-counting to only close the
|
||||||
|
//! underlying resource once all file descriptors referencing it are closed. That's why `Arc` (and
|
||||||
|
//! not `Box`) is the closest Rust analogy to an "owned" file descriptor.
|
||||||
|
//!
|
||||||
//! Like references, `BorrowedFd` values are tied to a lifetime, to ensure
|
//! Like references, `BorrowedFd` values are tied to a lifetime, to ensure
|
||||||
//! that they don't outlive the resource they point to. These are safe to
|
//! that they don't outlive the resource they point to. These are safe to
|
||||||
//! use. `BorrowedFd` values may be used in APIs which provide safe access to
|
//! use. `BorrowedFd` values may be used in APIs which provide safe access to
|
||||||
//! any system call except for:
|
//! any system call except for:
|
||||||
//!
|
//!
|
||||||
//! - `close`, because that would end the dynamic lifetime of the resource
|
//! - `close`, because that would end the dynamic lifetime of the resource
|
||||||
//! without ending the lifetime of the file descriptor.
|
//! without ending the lifetime of the file descriptor. (Equivalently:
|
||||||
|
//! an `&Arc<_>` cannot be `drop`ed.)
|
||||||
//!
|
//!
|
||||||
//! - `dup2`/`dup3`, in the second argument, because this argument is
|
//! - `dup2`/`dup3`, in the second argument, because this argument is
|
||||||
//! closed and assigned a new resource, which may break the assumptions
|
//! closed and assigned a new resource, which may break the assumptions of
|
||||||
//! other code using that file descriptor.
|
//! other code using that file descriptor.
|
||||||
//!
|
//!
|
||||||
//! `BorrowedFd` values may be used in APIs which provide safe access to `dup`
|
//! `BorrowedFd` values may be used in APIs which provide safe access to `dup` system calls, so code
|
||||||
//! system calls, so types implementing `AsFd` or `From<OwnedFd>` should not
|
//! working with `OwnedFd` cannot assume to have exclusive access to the underlying open file
|
||||||
//! assume they always have exclusive access to the underlying file
|
//! description. (Equivalently: `&Arc` may be used in APIs that provide safe access to `clone`, so
|
||||||
//! description.
|
//! code working with an `Arc` cannot assume that the reference count is 1.)
|
||||||
//!
|
//!
|
||||||
//! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the
|
//! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the
|
||||||
//! provided file descriptor in a manner similar to `dup` and does not require
|
//! provided file descriptor in a manner similar to `dup` and does not require
|
||||||
|
@ -52,8 +61,10 @@
|
||||||
//! take full responsibility for ensuring that safe Rust code cannot evoke
|
//! take full responsibility for ensuring that safe Rust code cannot evoke
|
||||||
//! undefined behavior through it.
|
//! undefined behavior through it.
|
||||||
//!
|
//!
|
||||||
//! Like boxes, `OwnedFd` values conceptually own the resource they point to,
|
//! Like `Arc`, `OwnedFd` values conceptually own one reference to the resource they point to,
|
||||||
//! and free (close) it when they are dropped.
|
//! and decrement the reference count when they are dropped (by calling `close`).
|
||||||
|
//! When the reference count reaches 0, the underlying open file description will be freed
|
||||||
|
//! by the kernel.
|
||||||
//!
|
//!
|
||||||
//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
|
//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
|
||||||
//!
|
//!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue