Create an owning handle to the given index's associated type. This will prevent the associated type from being unregistered as long as the returned `RegisteredType` is kept alive.
(engine: &Engine, index: VMSharedTypeIndex)
| 394 | /// This will prevent the associated type from being unregistered as long as |
| 395 | /// the returned `RegisteredType` is kept alive. |
| 396 | pub fn root(engine: &Engine, index: VMSharedTypeIndex) -> RegisteredType { |
| 397 | engine.signatures().debug_assert_contains(index); |
| 398 | |
| 399 | let (entry, ty, layout) = { |
| 400 | let id = shared_type_index_to_slab_id(index); |
| 401 | let inner = engine.signatures().0.read(); |
| 402 | |
| 403 | let ty = inner.types[id].clone().unwrap(); |
| 404 | let entry = inner.type_to_rec_group[index].clone().unwrap(); |
| 405 | let layout = inner.type_to_gc_layout.get(index).and_then(|l| l.clone()); |
| 406 | |
| 407 | // NB: make sure to incref while the lock is held to prevent: |
| 408 | // |
| 409 | // * This thread: read locks registry, gets entry E, unlocks registry |
| 410 | // * Other thread: drops `RegisteredType` for entry E, decref |
| 411 | // reaches zero, write locks registry, unregisters entry |
| 412 | // * This thread: increfs entry, but it isn't in the registry anymore |
| 413 | entry.incref("RegisteredType::root"); |
| 414 | |
| 415 | (entry, ty, layout) |
| 416 | }; |
| 417 | |
| 418 | RegisteredType::from_parts(engine.clone(), entry, index, ty, layout) |
| 419 | } |
| 420 | |
| 421 | /// Construct a new `RegisteredType`. |
| 422 | /// |