Changing singleton to be thread safe (nw)

This commit is contained in:
Brad Hughes 2016-11-20 11:36:04 -05:00
parent 7e327d5d4e
commit af289d1c30
4 changed files with 17 additions and 9 deletions

View File

@ -69,15 +69,15 @@ static const float POINTS_PER_DIP = (3.0f / 4.0f);
// Dynamic APIs // Dynamic APIs
DYNAMIC_API_BEGIN(d2d1, "d2d1.dll") DYNAMIC_API_BEGIN(d2d1, "d2d1.dll")
DYNAMIC_API_FN(HRESULT, WINAPI, D2D1CreateFactory, D2D1_FACTORY_TYPE, REFIID, const D2D1_FACTORY_OPTIONS *, void **) DYNAMIC_API_FN(HRESULT, WINAPI, D2D1CreateFactory, D2D1_FACTORY_TYPE, REFIID, const D2D1_FACTORY_OPTIONS *, void **)
DYNAMIC_API_END() DYNAMIC_API_END(d2d1)
DYNAMIC_API_BEGIN(dwrite, "dwrite.dll") DYNAMIC_API_BEGIN(dwrite, "dwrite.dll")
DYNAMIC_API_FN(HRESULT, WINAPI, DWriteCreateFactory, DWRITE_FACTORY_TYPE, REFIID, IUnknown **) DYNAMIC_API_FN(HRESULT, WINAPI, DWriteCreateFactory, DWRITE_FACTORY_TYPE, REFIID, IUnknown **)
DYNAMIC_API_END() DYNAMIC_API_END(dwrite)
DYNAMIC_API_BEGIN(locale, "kernel32.dll") DYNAMIC_API_BEGIN(locale, "kernel32.dll")
DYNAMIC_API_FN(int, WINAPI, GetUserDefaultLocaleName, LPWSTR, int) DYNAMIC_API_FN(int, WINAPI, GetUserDefaultLocaleName, LPWSTR, int)
DYNAMIC_API_END() DYNAMIC_API_END(locale)
// Debugging functions // Debugging functions
#ifdef DWRITE_DEBUGGING #ifdef DWRITE_DEBUGGING

View File

@ -19,6 +19,7 @@
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include <memory>
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
osd_process_kill: kill the current process osd_process_kill: kill the current process
@ -104,7 +105,7 @@ protected:
// //
// DYNAMIC_API_BEGIN(dxgi, "dxgi.dll") // DYNAMIC_API_BEGIN(dxgi, "dxgi.dll")
// DYNAMIC_API_FN(DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**) // DYNAMIC_API_FN(DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**)
// DYNAMIC_API_END() // DYNAMIC_API_END(dxgi)
// //
// Calling then looks like: DYNAMIC_CALL(dxgi, CreateDXGIFactory1, p1, p2, etc) // Calling then looks like: DYNAMIC_CALL(dxgi, CreateDXGIFactory1, p1, p2, etc)
//========================================================================================================================= //=========================================================================================================================
@ -115,12 +116,19 @@ protected:
class apiname##_api { \ class apiname##_api { \
private: \ private: \
osd::dynamic_module::ptr m_module = osd::dynamic_module::open( { __VA_ARGS__ } ); \ osd::dynamic_module::ptr m_module = osd::dynamic_module::open( { __VA_ARGS__ } ); \
static std::unique_ptr<apiname##_api> s_instance; \
static std::once_flag s_once; \
public: \ public: \
static apiname##_api &instance() { static apiname##_api api; return api; } static apiname##_api &instance() { \
std::call_once( apiname##_api::s_once, [](std::unique_ptr<apiname##_api> &inst) { \
inst = std::make_unique<apiname##_api>(); }, s_instance); \
return *apiname##_api::s_instance.get(); }
#define DYNAMIC_API_FN(ret, conv, apifunc, ...) ret(conv *m_##apifunc##_pfn)( __VA_ARGS__ ) = m_module->bind<ret(conv *)( __VA_ARGS__ )>(#apifunc); #define DYNAMIC_API_FN(ret, conv, apifunc, ...) ret(conv *m_##apifunc##_pfn)( __VA_ARGS__ ) = m_module->bind<ret(conv *)( __VA_ARGS__ )>(#apifunc);
#define DYNAMIC_API_END() };}} #define DYNAMIC_API_END(apiname) }; \
std::once_flag apiname##_api::s_once; \
std::unique_ptr<apiname##_api> apiname##_api::s_instance = nullptr; }}
#define DYNAMIC_CALL(apiname, fname, ...) (*osd::dynamicapi::apiname##_api::instance().m_##fname##_pfn) ( __VA_ARGS__ ) #define DYNAMIC_CALL(apiname, fname, ...) (*osd::dynamicapi::apiname##_api::instance().m_##fname##_pfn) ( __VA_ARGS__ )
#define DYNAMIC_API_TEST(apiname, fname) (osd::dynamicapi::apiname##_api::instance().m_##fname##_pfn != nullptr) #define DYNAMIC_API_TEST(apiname, fname) (osd::dynamicapi::apiname##_api::instance().m_##fname##_pfn != nullptr)
@ -129,7 +137,7 @@ public: \
#define DYNAMIC_API_BEGIN(apiname, ...) #define DYNAMIC_API_BEGIN(apiname, ...)
#define DYNAMIC_API_FN(ret, conv, apifunc, ...) #define DYNAMIC_API_FN(ret, conv, apifunc, ...)
#define DYNAMIC_API_END() #define DYNAMIC_API_END(apiname)
#define DYNAMIC_CALL(apiname, fname, ...) fname( __VA_ARGS__ ) #define DYNAMIC_CALL(apiname, fname, ...) fname( __VA_ARGS__ )
#define DYNAMIC_API_TEST(apiname, fname) (true) #define DYNAMIC_API_TEST(apiname, fname) (true)

View File

@ -27,7 +27,7 @@
DYNAMIC_API_BEGIN(dxgi, "dxgi.dll") DYNAMIC_API_BEGIN(dxgi, "dxgi.dll")
DYNAMIC_API_FN(DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**) DYNAMIC_API_FN(DWORD, WINAPI, CreateDXGIFactory1, REFIID, void**)
DYNAMIC_API_END() DYNAMIC_API_END(dxgi)
using namespace Microsoft::WRL; using namespace Microsoft::WRL;

View File

@ -127,7 +127,7 @@ typedef std::unique_ptr<IXAudio2SourceVoice, xaudio2_custom_deleter> src_voice_p
// //
DYNAMIC_API_BEGIN(xaudio2, "XAudio2_9.dll", "XAudio2_8.dll") DYNAMIC_API_BEGIN(xaudio2, "XAudio2_9.dll", "XAudio2_8.dll")
DYNAMIC_API_FN(HRESULT, WINAPI, XAudio2Create, IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR) DYNAMIC_API_FN(HRESULT, WINAPI, XAudio2Create, IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR)
DYNAMIC_API_END() DYNAMIC_API_END(xaudio2)
//============================================================ //============================================================
// Helper classes // Helper classes