-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathcache.rs
More file actions
66 lines (59 loc) · 1.92 KB
/
cache.rs
File metadata and controls
66 lines (59 loc) · 1.92 KB
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use std::os::raw::c_void;
use std::ptr;
use std::sync::atomic::{AtomicPtr, Ordering};
use crate::runtime::{self, Class, Sel};
/// Allows storing a `Sel` in a static and lazily loading it.
#[doc(hidden)]
pub struct CachedSel {
ptr: AtomicPtr<c_void>,
}
impl CachedSel {
/// Constructs a new `CachedSel`.
pub const fn new() -> CachedSel {
CachedSel {
ptr: AtomicPtr::new(ptr::null_mut()),
}
}
/// Returns the cached selector. If no selector is yet cached, registers
/// one with the given name and stores it.
#[inline(always)]
pub unsafe fn get(&self, name: &str) -> Sel {
let ptr = self.ptr.load(Ordering::Relaxed);
// It should be fine to use `Relaxed` ordering here because `sel_registerName` is
// thread-safe.
if ptr.is_null() {
let sel = runtime::sel_registerName(name.as_ptr() as *const _);
self.ptr.store(sel.as_ptr() as *mut _, Ordering::Relaxed);
sel
} else {
Sel::from_ptr(ptr)
}
}
}
/// Allows storing a `Class` reference in a static and lazily loading it.
#[doc(hidden)]
pub struct CachedClass {
ptr: AtomicPtr<Class>,
}
impl CachedClass {
/// Constructs a new `CachedClass`.
pub const fn new() -> CachedClass {
CachedClass {
ptr: AtomicPtr::new(ptr::null_mut()),
}
}
/// Returns the cached class. If no class is yet cached, gets one with
/// the given name and stores it.
#[inline(always)]
pub unsafe fn get(&self, name: &str) -> Option<&'static Class> {
// `Relaxed` should be fine since `objc_getClass` is thread-safe.
let ptr = self.ptr.load(Ordering::Relaxed);
if ptr.is_null() {
let cls = runtime::objc_getClass(name.as_ptr() as *const _);
self.ptr.store(cls as *mut _, Ordering::Relaxed);
cls.as_ref()
} else {
Some(&*ptr)
}
}
}