Dealing with thread-unsafe initialization of C libraries


#1

I would like to bind to the ultra-fast chacha-opt library. However, it has an initialization function that isn’t thread safe. I could modify the library so that its initialization is thread-safe, but I would prefer to avoid modifying it. How can this be handled?


#2

You can use std::sync::Once to add synchronization on top of chacha-opt’s initialization function:

pub fn init() {
    static ONCE: Once = ONCE_INIT;

    ONCE.call_once(|| {
        // you'll also want do do something with the failure case here
        unsafe { chacha_startup(); }
    }
}

#3

How do I prevent users from using the library before it has been initialized?


#4

That’s easy. Just require the user to pass an witness to the initialization to every function.


#5

Alternatively, simply call init in every entry point function in your API if the number of those is small enough.


#6

Won’t work: the init function must be complete before any thread can use
the library.


#7

Once::call_once will block if another thread is already running it. If you get past that, your initialization should be complete.