MCPcopy Create free account
hub / github.com/bytecodealliance/rustix / get

Method get

src/weak.rs:67–100  ·  view source on GitHub ↗
(&self)

Source from the content-addressed store, hash-verified

65 }
66
67 pub(crate) fn get(&self) -> Option<F> {
68 assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());
69 unsafe {
70 // Relaxed is fine here because we fence before reading through the
71 // pointer (see the comment below).
72 match self.addr.load(Ordering::Relaxed) {
73 INVALID => self.initialize(),
74 NULL => None,
75 addr => {
76 let func = mem::transmute_copy::<*mut c_void, F>(&addr);
77 // The caller is presumably going to read through this
78 // value (by calling the function we've dlsymed). This
79 // means we'd need to have loaded it with at least C11's
80 // consume ordering in order to be guaranteed that the data
81 // we read from the pointer isn't from before the pointer
82 // was stored. Rust has no equivalent to
83 // memory_order_consume, so we use an acquire fence (sorry,
84 // ARM).
85 //
86 // Now, in practice this likely isn't needed even on CPUs
87 // where relaxed and consume mean different things. The
88 // symbols we're loading are probably present (or not) at
89 // init, and even if they aren't the runtime dynamic loader
90 // is extremely likely have sufficient barriers internally
91 // (possibly implicitly, for example the ones provided by
92 // invoking `mprotect`).
93 //
94 // That said, none of that's *guaranteed*, and so we fence.
95 atomic::fence(Ordering::Acquire);
96 Some(func)
97 }
98 }
99 }
100 }
101
102 // Cold because it should only happen during first-time initialization.
103 #[cold]

Callers 5

as_rawMethod · 0.45
as_raw_pidMethod · 0.45
as_rawMethod · 0.45
is_initMethod · 0.45

Calls 1

initializeMethod · 0.45

Tested by

no test coverage detected