11// dllmain.cpp : Defines the entry point for the DLL application.
2- #include < stdlib.h>
32#include " ../../src/CommonInc.h"
43#include " ../../src/MathWorker.h"
54#include " ../../src/SDSFile.h"
65
6+ #include < mutex>
7+ #include < stdlib.h>
8+
79// #define LOGGING printf
810#define LOGGING (...)
911
1012// ----------------------------------------------------------------------------------
11- CMathWorker * g_cMathWorker = new CMathWorker();
12- bool g_bStarted = false ;
13+ CMathWorker * g_cMathWorker = nullptr ; // new CMathWorker();
14+
15+ namespace
16+ {
17+ // Starting working threads requires thread synchronization, so it cannot be
18+ // called from DllMain or from static object.
19+ // Each API needs to call ensure_threads_started() to ensure that threads have been
20+ // started prior to continuing.
21+
22+ std::once_flag g_bStarted{};
23+
24+ void ensure_threads_started ()
25+ {
26+ std::call_once (g_bStarted,
27+ []()
28+ {
29+ g_cMathWorker = new CMathWorker ();
30+ g_cMathWorker->StartWorkerThreads (0 );
31+ });
32+ }
33+ }
1334
1435static int64_t g_TotalAllocs = 0 ;
1536static int64_t g_TotalFree = 0 ;
@@ -140,18 +161,10 @@ uint64_t GetUTCNanos()
140161#if defined(_WIN32)
141162bool APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
142163{
164+ // NOTE: Cannot do any thread-related work in DllMain.
143165 switch (ul_reason_for_call)
144166 {
145167 case DLL_PROCESS_ATTACH:
146-
147- if (! g_bStarted)
148- {
149- g_bStarted = true ;
150-
151- // default to numa node 0
152- g_cMathWorker->StartWorkerThreads (0 );
153- }
154- break ;
155168 case DLL_THREAD_ATTACH:
156169 case DLL_THREAD_DETACH:
157170 case DLL_PROCESS_DETACH:
@@ -419,6 +432,8 @@ extern "C"
419432 // pointer to stReadSharedMemory
420433 RT_DLLEXPORT stReadSharedMemory * ReadFromSharedMemory (const char * fileName, const char * shareName)
421434 {
435+ ensure_threads_started ();
436+
422437 // uint64_t fileNameSize;
423438 // uint64_t shareNameSize = 0;
424439
@@ -815,6 +830,8 @@ extern "C"
815830 const char * inListNames, // use commas to separate
816831 int64_t totalRows, int64_t bandSize = 0 )
817832 {
833+ ensure_threads_started ();
834+
818835 bool result = CreateSDSFileInternal (fileName, shareName, metaData,
819836 inListNames, // use commas to separate
820837 totalRows, bandSize);
@@ -829,10 +846,11 @@ extern "C"
829846 // shareName: the sharename the user provided, may be NULL
830847 // Returns:
831848 // true/false
832- RT_DLLEXPORT bool AppendSDSFile (const char * outFileName,
833-
834- const char * shareFileName, const char * shareName, int64_t totalRows, int64_t bandSize = 0 )
849+ RT_DLLEXPORT bool AppendSDSFile (const char * outFileName, const char * shareFileName, const char * shareName,
850+ int64_t totalRows, int64_t bandSize = 0 )
835851 {
852+ ensure_threads_started ();
853+
836854 stReadSharedMemory * pSharedMemory = (stReadSharedMemory *)ReadFromSharedMemory (shareFileName, shareName);
837855 if (pSharedMemory)
838856 {
0 commit comments