Skip to content

Commit

Permalink
update doubly linked list commentary and fix links
Browse files Browse the repository at this point in the history
  • Loading branch information
fu5ha committed Sep 25, 2023
1 parent c13e11a commit 8e1c903
Showing 1 changed file with 19 additions and 15 deletions.
34 changes: 19 additions & 15 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,29 +376,34 @@
//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
//! ```
//!
//! ## Intrusive, doubly-linked list
//! ## An intrusive, doubly-linked list
//! [linked-list]: #an-intrusive-doubly-linked-list
//!
//! In an intrusive doubly-linked list, the collection does not actually allocate the memory for the
//! nodes itself. Allocation is controlled by the clients, and nodes can live on a stack frame
//! that lives shorter than the collection does provided the nodes are removed from the
//! collection before returning.
//!
//! The full implementation details of such a data structure are outside the scope of this
//! documentation, but we will discuss how [`Pin`] can help to do so.
//!
//! To make this work, every element has pointers to its predecessor and successor in
//! the list. Elements can only be added when they are pinned, because moving the elements
//! around would invalidate the pointers. Moreover, the [`Drop`][Drop] implementation of a linked
//! list element will patch the pointers of its predecessor and successor to remove itself
//! from the list.
//! To make such an intrusive data structure work, every element stores pointers to its predecessor
//! and successor within its own data, rather than having the list structure itself manage those
//! pointers. Elements can only be added when they are pinned, because moving the elements
//! around would invalidate the pointers to it which are contained in the element ahead and behind
//! it. Moreover, the [`Drop`][Drop] implementation of the element types themselves will in some
//! way patch the pointers of its predecessor and successor elements to remove itself from the list.
//!
//! Crucially, we have to be able to rely on [`drop`] being called before an element is invalidated.
//! If an element could be deallocated or otherwise invalidated without calling [`drop`], the
//! pointers into it from its neighboring elements would become invalid, which would break the data
//! structure.
//! Crucially, this means we have to be able to rely on [`drop`] always being called before that
//! element is invalidated. If an element could be deallocated or otherwise invalidated without
//! calling [`drop`], the pointers into it which are stored in its neighboring elements would
//! become invalid, which would break the data structure.
//!
//! Therefore, we rely on [the `Drop` guarantee][drop-guarantee] which comes with pinning data.
//! Therefore, we rely on [the `Drop` guarantee][drop-guarantee] which comes with pinning data,
//!
//! # Subtle details
//! [subtle-details]: #subtle-details
//! # Subtle details and the `Drop` guarantee
//! [subtle-details]: self#subtle-details-and-the-drop-guarantee
//! [drop-guarantee]: self#subtle-details-and-the-drop-guarantee
//!
//! The purpose of pinning is not *just* to prevent a value from being *moved*, but rather more
//! generally to be able to rely on the pinned value *remaining valid **at a specific place*** in
Expand All @@ -425,7 +430,6 @@
//! This point is subtle but required for intrusive data structures to be implemented soundly.
//!
//! ## `Drop` guarantee
//! [drop-guarantee]: self#drop-guarantee
//!
//! There needs to be a way for a pinned value to notify any code that is relying on its pinned
//! status that it is about to be destroyed, so that such code can remove its address from their
Expand Down Expand Up @@ -482,7 +486,7 @@
//! address-sensitive types, which are different from merely using [`Pin<P>`] in a generic
//! way.
//!
//! ## Implementing [`Drop`] for types with address-sensitive state
//! ## Implementing [`Drop`] for types with address-sensitive states
//! [drop-impl]: self#implementing-drop-for-types-with-address-sensitive-states
//!
//! The [`drop`] function takes [`&mut self`], but this is called *even if that `self` has been
Expand Down

0 comments on commit 8e1c903

Please sign in to comment.