[String] Use alternateive VAProvider when uninitializing

Using thread-local VAProviders in the uninitialization routine is not
possible, as thread storage has already been destroyed
This commit is contained in:
momo5502 2017-06-04 13:46:50 +02:00
parent 0449fcef35
commit c8f80ceee0
4 changed files with 26 additions and 5 deletions

View File

@ -4,6 +4,7 @@ namespace Components
{ {
bool Loader::Pregame = true; bool Loader::Pregame = true;
bool Loader::Postgame = false; bool Loader::Postgame = false;
bool Loader::Uninitializing = false;
bool Loader::ComInitialized = false; bool Loader::ComInitialized = false;
std::vector<Component*> Loader::Components; std::vector<Component*> Loader::Components;
@ -17,6 +18,11 @@ namespace Components
return Loader::Postgame; return Loader::Postgame;
} }
bool Loader::IsUninitializing()
{
return Loader::Uninitializing;
}
bool Loader::IsComInitialized() bool Loader::IsComInitialized()
{ {
return Loader::ComInitialized; return Loader::ComInitialized;
@ -26,6 +32,7 @@ namespace Components
{ {
Loader::Pregame = true; Loader::Pregame = true;
Loader::Postgame = false; Loader::Postgame = false;
Loader::Uninitializing = false;
Utils::Memory::GetAllocator()->clear(); Utils::Memory::GetAllocator()->clear();
Loader::ComInitialized = false; Loader::ComInitialized = false;
@ -106,6 +113,7 @@ namespace Components
void Loader::Uninitialize() void Loader::Uninitialize()
{ {
Loader::Uninitializing = true;
Loader::PreDestroyNoPostGame(); Loader::PreDestroyNoPostGame();
std::reverse(Loader::Components.begin(), Loader::Components.end()); std::reverse(Loader::Components.begin(), Loader::Components.end());
@ -124,6 +132,7 @@ namespace Components
Utils::Memory::GetAllocator()->clear(); Utils::Memory::GetAllocator()->clear();
if (!Loader::PerformingUnitTests() && !Utils::IsWineEnvironment() && Loader::ComInitialized) CoUninitialize(); if (!Loader::PerformingUnitTests() && !Utils::IsWineEnvironment() && Loader::ComInitialized) CoUninitialize();
Loader::Uninitializing = false;
} }
void Loader::PreDestroy() void Loader::PreDestroy()

View File

@ -37,6 +37,7 @@ namespace Components
static bool IsPregame(); static bool IsPregame();
static bool IsPostgame(); static bool IsPostgame();
static bool IsUninitializing();
static bool IsComInitialized(); static bool IsComInitialized();
template <typename T> template <typename T>
@ -56,6 +57,7 @@ namespace Components
private: private:
static bool Pregame; static bool Pregame;
static bool Postgame; static bool Postgame;
static bool Uninitializing;
static bool ComInitialized; static bool ComInitialized;
static std::vector<Component*> Components; static std::vector<Component*> Components;
}; };

View File

@ -9,11 +9,16 @@ namespace Utils
{ {
const char *VA(const char *fmt, ...) const char *VA(const char *fmt, ...)
{ {
static VAProvider<4, 100> globalProvider;
static thread_local VAProvider<8, 256> provider; static thread_local VAProvider<8, 256> provider;
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
const char* result = provider.get(fmt, ap);
const char* result;
if(Components::Loader::IsUninitializing()) result = globalProvider.get(fmt, ap);
else result = provider.get(fmt, ap);
va_end(ap); va_end(ap);
return result; return result;
} }

View File

@ -8,17 +8,19 @@ namespace Utils
class VAProvider class VAProvider
{ {
public: public:
VAProvider() : currentBuffer(0) {} static_assert(Buffers != 0 && MinBufferSize != 0, "Buffers and MinBufferSize mustn't be 0");
typename std::enable_if<(Buffers != 0 && MinBufferSize != 0), char*>::type VAProvider() : currentBuffer(0) {}
get(const char* format, va_list ap) ~VAProvider() {}
char* get(const char* format, va_list ap)
{ {
++this->currentBuffer %= ARRAYSIZE(this->stringPool); ++this->currentBuffer %= ARRAYSIZE(this->stringPool);
auto entry = &this->stringPool[this->currentBuffer]; auto entry = &this->stringPool[this->currentBuffer];
if (!entry->size || !entry->buffer) if (!entry->size || !entry->buffer)
{ {
*entry = Entry(MinBufferSize); throw std::runtime_error("String pool not initialized");
} }
while (true) while (true)
@ -46,6 +48,8 @@ namespace Utils
~Entry() ~Entry()
{ {
if(this->buffer) Utils::Memory::GetAllocator()->free(this->buffer); if(this->buffer) Utils::Memory::GetAllocator()->free(this->buffer);
this->size = 0;
this->buffer = nullptr;
} }
void allocate() void allocate()
@ -64,6 +68,7 @@ namespace Utils
char* buffer; char* buffer;
}; };
size_t currentBuffer; size_t currentBuffer;
Entry stringPool[Buffers]; Entry stringPool[Buffers];
}; };