CnxSharedTimedMutex struct

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