CnxSharedTimedMutex struct
#include <include/Cnx/sync/SharedMutex.h>
CnxSharedTimedMutex
is a higher-level reader-writer mutex type for use when timed backoff of mutex locking is required, and is directly comparable to C++'s std::shared_timed_mutex
. It allows for specifying a timeout, which if reached will cause execution to stop attempting to acquire the lock and signal failure to the caller, instead of blocking indefinitely until the lock was successfully acquired like a tradition mutex. For example, if an algorithm needs reader-writer synchronization, but blocking for longer than X milliseconds when trying to acquire the lock would be problematic, a CnxSharedTimedMutex
would be the appropriate mutex type to use.
Example:
// MyThing.h #include <Cnx/sync/SharedMutex.h> static MyType my_very_important_thing; static CnxSharedMutex* my_thing_mutex; void init_my_thing(void); bool update_my_thing(u64 value); u64 get_value_from_my_thing(void); // MyThing.c #include <Cnx/Allocators.h> #include "MyThing.h" void init_my_thing(void) { if(my_thing_mutex == nullptr) { my_thing_mutex = cnx_allocator_allocate_t(CnxSharedTimedMutex, DEFAULT_ALLOCATOR); *my_thing_mutex = cnx_shared_timed_mutex_new(); cnx_shared_timed_mutex_lock(my_thing_mutex); my_very_important_thing = { // important intialization }; cnx_shared_timed_mutex_unlock(my_thing_mutex); } } // only one thread at a time can `update_my_thing`, because it uses exclusive locking bool update_my_thing(u64 value) { // we can only afford to wait 50 milliseconds to update the value before we need to start // doing more calculations if(cnx_shared_timed_mutex_try_lock_for(my_thing_mutex, cnx_milliseconds(50))) { my_very_important_thing.value = value; return true; } return false; } // any number of threads can `get_value_from_my_thing` without blocking eachother, // because it uses shared locking. u64 get_value_from_my_thing(void) { cnx_shared_timed_mutex_lock_shared(my_thing_mutex); let val = my_very_important_thing.value; cnx_shared_timed_mutex_unlock_shared(my_thing_mutex); return val; } loop { // do some compute intensive task... // try to update the value if(!update_my_thing(new_value)) { fprintln(log_file, "INFO: Failed to update value"); } } my_val = get_value_from_my_thing(); // do something with my_val let_mut newval = get_value_from_my_thing(); while(newval == my_val) { cnx_this_thread_sleep_for(cnx_milliseconds(100)); newval = get_value_from_my_thing(); } my_val = newval; // do something with new value