No, that's not exagerating for clickbait; it's true. It's an edge case, but Rust's safety rules don't allow for edge cases without saying unsafe
.
Creating an FMOD Core System or an FMOD Studio System is thread-unsafe to any other FMOD API call (including themselves). To make matters even more "interesting", releasing them is thread-unsafe as well!
Even more fun, there's a flag that explicitly requests everything to be thread unsafe.
No FMOD binding that I can find protects against this unsoundness. Even assuming every other API surface is wrapped soundly, every FMOD existing binding is unsound.
This crate takes a simple enough approach, which is decently common for FFI wrappers:
control System
creation, so that only one is ever created. All owned library handles own a reference count to the global System
.
This isn't 100% zero-cost — resources could be instead bound to the lifetime of the System
— but it is much easier to work with.
If desired, I can add a RefHandle
to put that lifetime on which uses +0 reference counting to make it near-zero-cost.
The only remaining cost would be the global lock and pointer on the System
singleton, which is unavoidable in a sound API.