[−][src]Macro zerogc::unsafe_trace_lock
Unsafely implement GarbageCollected
for the specified type,
by acquiring a 'lock' in order to trace the underlying value.
This is good for interior mutability types like RefCell
and Mutex
where you need to acquire a lock,
in order to safely view the interior.
Usually unsafe_trace_deref!
is sufficient since it also lets you run
arbitrary code in order to 'convert' the macro to the necessary type,
and the only restriction is that the interior can be directly traced.
However, that isn't sufficient if you need to hold RAII guards (like Ref
or MutexGuard
s)
on the values you're tracing in addition to just accessing them.
For example, for RefCell
you'd call borrow
in order to acquire a Ref
to the interior.
Although tracing garbage collection is already unsafe,
it's always completely undefined behavior to bypass the locking of Mutex
and RefCell
,
even if it's just for a 'little bit' since it may cause mutable references to alias.
It is currently the most powerful of the unsafe implementation macros,
since it lets you not only run an arbitrary expression like unsafe_trace_deref!
,
but also acquire and hold a RAII guard object.
This macro is usually only useful for types like Mutex
and RefCell
who use raw pointers internally,
since raw pointers can't be automatically traced without additional type information.
Otherwise, it's best to use an automatically derived implementation since that's always safe.
However, using this macro is always better than a manual implementation, since it makes your intent clearer.
Usage
// You can use an arbitrary expression to acquire a lock's guard unsafe_trace_lock!(RefCell, target = T, |cell| cell.borrow()); unsafe_trace_lock!(Mutex, target = T, |lock| lock.lock().unwrap()); unsafe_trace_lock!(RwLock, target = T, |lock| lock.lock().unwrap());
Safety
Always prefer automatically derived implementations where possible,
since they're just as fast and can never cause undefined behavior.
This is basically an unsafe automatically derived implementation,
to be used only when a safe automatically derived implementation isn't possible (like with Vec
).
Undefined behavior if there could be additional garbage collected objects that are not reachable by dereferencing the specified lock, since the macro only traces the item the lock dereferences to. This usually isn't the case with most locks and would be somewhat rare, but it's still a possibility that causes the macro to be unsafe.
This delegates to unsafe_gc_brand
to provide the GcBrand
implementation,
so that could also trigger undefined behavior.