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

View File

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

View File

@ -9,11 +9,16 @@ namespace Utils
{
const char *VA(const char *fmt, ...)
{
static VAProvider<4, 100> globalProvider;
static thread_local VAProvider<8, 256> provider;
va_list ap;
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);
return result;
}

View File

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