Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I initialize thread primitives from a multithreaded context with win32?

I want to create a static Lock

void foo(){
    static CRITICAL_SECTION *lock = NULL; //this is the problem, I cannot create any primitive to do this with win32 threads
    static long isInitialized = 0;
    if (InterlockedExchange(&isInitialized, 1) == 0){ //this will ensure that lock is initialized only once
        lock = (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION));
        InitializeCriticalSection(lock);
    }
    EnterCriticalSection(lock); //this might be called before initialization is done...YIKES!
    ...
    LeaveCriticalSection(lock); 
}

How do I initialize the lock from a multithreaded context?

A crappy solution could look like:

void foo(){
    static CRITICAL_SECTION *lock = NULL; //this is the problem, I cannot create any primitive to do this with win32 threads
    static long isInitialized = 0;
    static volatile long isInitializeDone = 0;
    if (InterlockedExchange(&isInitialized, 1) == 0){ //this will ensure that lock is initialized only once
        lock = (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION));
        InitializeCriticalSection(lock);
        isInitializeDone = 1;
    } else {
        while (isInitializeDone == 0){

        }
    }
    EnterCriticalSection(lock); //this might be called before initialization is done...YIKES!
    ...
    LeaveCriticalSection(lock); 
}

but is there a better solution?

like image 489
chacham15 Avatar asked Dec 04 '25 08:12

chacham15


1 Answers

If this is C++, you can call a function to initialize that critical section:

static CRITICAL_SECTION *lock = get_critical_section();

like

CRITICAL_SECTION* get_critical_section()
{
    CRITICAL_SECTION *lock = NULL;
    InitializeCriticalSection(&lock);
    return lock;
}

C++ specifies that exactly one thread will initialize that thing, and that all other threads will wait for it:

[stmt.dcl]

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

EDIT: I don't know since when the text within the standard is like this, but I'm pretty sure this is what all implementations do.

like image 124
pentadecagon Avatar answered Dec 05 '25 23:12

pentadecagon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!