capypad
0 Tage Serie
rust / expert
Snippet

Pinned Memory für Async State Machines

Der 'Pin'-Wrapper stellt sicher, dass ein Wert an einer festen Speicheradresse bleibt. Dies ist kritisch für selbstreferenzierende Strukturen, bei denen ein Feld einen Pointer auf ein anderes Feld im selben Objekt speichert. Wenn das Objekt verschoben würde, würde der interne Pointer ungültig.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use std::pin::Pin;
use std::marker::PhantomPinned;
 
struct SelfReferential {
data: String,
ptr: *const String,
_pin: PhantomPinned,
}
 
impl SelfReferential {
pub fn new(data: String) -> Pin<Box<Self>> {
let res = SelfReferential {
data,
ptr: std::ptr::null(),
_pin: PhantomPinned,
};
let mut boxed = Box::pin(res);
let self_ptr: *const String = &boxed.data;
unsafe {
let mut_ref: Pin<&mut Self> = boxed.as_mut();
Pin::get_unchecked_mut(mut_ref).ptr = self_ptr;
}
boxed
}
}
Erklärung
1
_pin: PhantomPinned,
Ein Marker, der dem Compiler mitteilt, dass dieser Typ den Unpin-Trait nicht implementiert.
2
let mut boxed = Box::pin(res);
Allokiert die Struktur auf dem Heap und 'pinned' sie, um ein Verschieben zu verhindern.