steinbergmedia / vstgui

A user interface toolkit mainly for audio plug-ins
Other
880 stars 124 forks source link

Custom Fonts on Windows broken if ExitDll called but DLL not actually unloaded #330

Closed nickdowell closed 2 months ago

nickdowell commented 3 months ago

Steps to reproduce:

D2DFont::terminate () (called from ExitDll ()) resets customFonts but since customFontsOnceFlag is not and cannot be reset, customFonts will never be recreated by subsequent calls to getCustomFonts () unless the plug-in's DLL is removed from memory, which may not always happen.

static std::unique_ptr<CustomFonts> customFonts;
static std::once_flag customFontsOnceFlag;

static CustomFonts* getCustomFonts ()
{
    std::call_once (customFontsOnceFlag, [] () { customFonts = std::make_unique<CustomFonts> (); });
    return customFonts.get ();
}

void D2DFont::terminate () { D2DFontPrivate::customFonts = nullptr; }

One work-around is to comment out the body of D2DFont::terminate ()


Update: I was seeing this behaviour due to a long-running thread in my plug-in that was expecting to be torn down in a static destructor. This increased the DLL's reference count thereby preventing unloading. Using a static Steinberg::ModuleTerminator to terminate the thread has resolved the issue, but I still think this use of a static std::once_flag is problematic due to the uncertainty around library unloading.