Module ffi_support::handle_map [−][src]
This module provides a Handle
type, which you can think of something
like a dynamically checked, type erased reference/pointer type. Depending on
the usage pattern a handle can behave as either a borrowed reference, or an
owned pointer.
They can be losslessly converted to and
from a 64 bit integer, for ease of passing over the FFI
(and they implement IntoFfi
using these primitives for this purpose).
The benefit is primarially that they can detect common misuse patterns that would otherwise be silent bugs, such as use-after-free, double-free, passing a wrongly-typed pointer to a function, etc.
Handles are provided when inserting an item into either a HandleMap
or a
ConcurrentHandleMap
.
Comparison to types from other crates
HandleMap
is similar to types offered by other crates, such as
slotmap
, or slab
. However, it has a number of key differences which make
it better for our purposes as compared to the types in those crates:
- Unlike
slab
(but likeslotmap
), we implement versioning, detecting ABA problems, which allows us to detect use after free. - Unlike
slotmap
, we don’t have theT: Copy
restriction. - Unlike either, we can detect when you use a Key in a map that did not
allocate the key. This is true even when the map is from a
.so
file compiled separately. - Our implementation of doesn’t use any
unsafe
(at the time of this writing).
However, it comes with the following drawbacks:
slotmap
holds its version information in au32
, and so it takes 231 colliding insertions and deletions before it could potentially fail to detect an ABA issue, wheras we use au16
, and are limited to 215.- Similarly, we can only hold 216 items at once, unlike
slotmap
’s 232. (Considering these items are typically things like database handles, this is probably plenty). - Our implementation is slower, and uses slightly more memory than
slotmap
(which is in part due to the lack ofunsafe
mentioned above)
The first two issues seem exceptionally unlikely, even for extremely
long-lived HandleMap
, and we’re still memory safe even if they occur (we
just might fail to notice a bug). The third issue also seems unimportant for
our use case.
Structs
ConcurrentHandleMap |
|
Handle | A Handle we allow to be returned over the FFI by implementing |
HandleMap |
|
Enums
HandleError | An error representing the ways a |
Constants
MAX_CAPACITY | The maximum capacity of a |