The way I understand `protect` and `dispose` is they are the inter-thread 
equivalent to `GC_ref` and `GC_unref` respectively.

Nim's per-thread GC only looks for roots in the current thread. If some objects 
can't be tracked using traced `ref`'s, i.e. using typed `ptr`'s or raw 
`pointer`'s, then you can use `GC_ref` and `GC_unref` to manually manage these 
untraced objects in the same thread. The typical use-case for this is when 
passing objects through FFI to C code.

When GC objects are passed across threads through `ptr` or `pointer`, then 
`protect` and `dispose` do the same thing, except they are thread-safe 
(GC_ref/unref can only be used in same thread). You obtain a `ForeignCell` 
handle from the thread that owns the object -- this ensures the object won't be 
inadvertently collected -- and then when you're done using it in the other 
thread(s), you call `dispose` on the `ForeignCell` to convey to the original GC 
thread that it can now collect the object if it's no longer in use. 

Reply via email to