Reputation: 813
Is it possible to initialise CRITICAL_SECTION
statically, as in pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
?
In other words, is it possible in C to initialize a global CRITICAL_SECTION
inside a library without having to mess with DllMain
etc.?
Upvotes: 2
Views: 1491
Reputation: 813
The answer above from Raymond Chen solves the problem: "You can use InitOnceExecuteOnce to initialize the critical section on first use. That's what PTHREAD_MUTEX_INITIALIZER
does under the covers."
note that this will work on Vista and above only --- @rkosegi
You can do it for older versions of Windows by writing your own
InitOnceExecuteOnce
function usingInterlockedCompareExchange
. --- @RaymondChen
Upvotes: 1
Reputation: 9844
Another possibility in earlier versions is to instruct the linker to set a pointer to your initialization function as a user-defined global initializer. There is some discussion of this here:
http://msdn.microsoft.com/en-us/library/bb918180.aspx
Here is an example:
CRITICAL_SECTION criticalSection;
static void __cdecl Initialize(void) {
InitializeCriticalSection(&criticalSection);
}
#pragma section(".CRT$XCU", read)
__declspec(allocate(".CRT$XCU"))
const void (__cdecl *pInitialize)(void) = Initialize;
Upvotes: 1
Reputation: 14628
Yes, simply initialize in DLL_PROCESS_ATTACH and delete in DLL_PROCESS_DETACH
CRITICAL_SECTION g_cs = {0};
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
InitializeCriticalSection(&g_cs);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
DeleteCriticalSection(&g_cs);
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
References:
Upvotes: 2
Reputation: 5194
Yes! But you have to make sure that it's only done once per process.
But this is typically easiest to achieve by using the DLL_PROCESS_ATTACH case of the DLLMain
switch( fdwReason )
statement.
Upvotes: 1