[*] Continue to refactor allocations of synchronization primitive away
[*] NT: Fix missing CoTaskMemFree leak on startup [*] Fix ConsoleStd restart bug
This commit is contained in:
parent
3563ece47b
commit
ca2c0462ab
@ -15,6 +15,7 @@
|
||||
#include "Locale/Locale.hpp"
|
||||
#include "Console/Console.hpp"
|
||||
#include "IO/FS/FS.hpp"
|
||||
#include "IO/FS/Resources.hpp"
|
||||
#include "IO/IO.hpp"
|
||||
#include "IO/Net/Net.hpp"
|
||||
#include "Hashing/AuHashing.hpp"
|
||||
@ -158,6 +159,9 @@ static void RuntimeLateClean()
|
||||
Aurora::IO::Deinit();
|
||||
Aurora::Exit::DeinitExit();
|
||||
|
||||
Aurora::IO::FS::DeinitResources();
|
||||
Aurora::CmdLine::Deinit();
|
||||
|
||||
Aurora::RNG::Release(); // RNG and crypto should remain alive whilst IO work is ongoing.
|
||||
// At this point, we should assume libtomcrypt and mbedtls wont be called
|
||||
// The default gFastDevice shouldn't be hit for any reason
|
||||
|
@ -142,4 +142,13 @@ namespace Aurora::CmdLine
|
||||
|
||||
ProcessArgs();
|
||||
}
|
||||
|
||||
void Deinit()
|
||||
{
|
||||
gCmdFlags.clear();
|
||||
gCmdValues.clear();
|
||||
gCmdValueMap.clear();
|
||||
gCmdFlagLookup.clear();
|
||||
gCmdLineString.clear();
|
||||
}
|
||||
}
|
@ -10,4 +10,5 @@
|
||||
namespace Aurora::CmdLine
|
||||
{
|
||||
void Init();
|
||||
void Deinit();
|
||||
}
|
@ -16,8 +16,8 @@ namespace Aurora::Console::Commands
|
||||
static AuHashMap<AuString, Command> gCommands;
|
||||
static AuList<Hooks::LineHook_cb> gLineCallbacks;
|
||||
static AuList<CommandDispatch> gPendingCommands;
|
||||
static auto gMutex = AuThreadPrimitives::MutexUnique();
|
||||
static auto gPendingCommandsMutex = AuThreadPrimitives::MutexUnique();
|
||||
static AuThreadPrimitives::Mutex gMutex;
|
||||
static AuThreadPrimitives::Mutex gPendingCommandsMutex;
|
||||
static Async::WorkerPId_t gCommandDispatcher;
|
||||
|
||||
struct Command
|
||||
|
@ -755,9 +755,10 @@ namespace Aurora::Console::ConsoleStd
|
||||
Console::AddDefaultLogger(AuUnsafeRaiiToShared(&Logging::Sinks::gStdConsoleSink));
|
||||
}
|
||||
|
||||
static bool gConsoleStarted = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
static bool gConsoleStarted = false;
|
||||
if (AuExchange(gConsoleStarted, true)) return;
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
@ -1594,6 +1595,7 @@ namespace Aurora::Console::ConsoleStd
|
||||
AuWin32CloseHandle(gOutputStream);
|
||||
#endif
|
||||
|
||||
gConsoleStarted = false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
static COORD gSavedCoord {};
|
||||
|
||||
static bool gIsRecording {};
|
||||
static AuThreadPrimitives::SpinLock gRecordLock;
|
||||
static AuThreadPrimitives::Mutex gRecordLock;
|
||||
static AuList<AuFunction<void()>> gRecordedActions {};
|
||||
|
||||
struct Console
|
||||
|
@ -310,7 +310,6 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
void TTYConsole::Init()
|
||||
{
|
||||
this->historyLock = AuThreadPrimitives::RWLockUnique();
|
||||
this->HistorySetFile();
|
||||
this->HistoryLoad();
|
||||
}
|
||||
@ -2329,9 +2328,14 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
void Init()
|
||||
{
|
||||
if (!gRuntimeConfig.console.enableConsole)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gTTYConsole.Init();
|
||||
|
||||
if (gMultiThreadTTY)
|
||||
if (gMultiThreadTTY && !gConsoleTTYThread)
|
||||
{
|
||||
gConsoleTTYThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
|
||||
AuMakeShared<AuThreads::IThreadVectorsFunctional>(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(MainTTY)),
|
||||
@ -2377,6 +2381,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
|
||||
void PumpForce()
|
||||
{
|
||||
// no more force deinit for.now:
|
||||
gConsoleTTYThread.reset();
|
||||
|
||||
gTTYConsole.Pump();
|
||||
|
@ -229,7 +229,7 @@ namespace Aurora::Console::ConsoleTTY
|
||||
int iHistoryWritePos {0};
|
||||
AuList<AuString> history;
|
||||
|
||||
AuThreadPrimitives::RWLockUnique_t historyLock;
|
||||
AuThreadPrimitives::RWLock historyLock;
|
||||
|
||||
|
||||
AuThreadPrimitives::SpinLock messageLock;
|
||||
|
@ -26,7 +26,7 @@
|
||||
class ConsoleFrame;
|
||||
|
||||
static AuList<Aurora::Console::ConsoleMessage> gPendingLines;
|
||||
static AuThreadPrimitives::MutexUnique_t gMutex;
|
||||
static AuThreadPrimitives::Mutex gMutex;
|
||||
static bool gWxConsoleReady;
|
||||
static bool gConsoleStarted = false;
|
||||
static ConsoleFrame *gWxFrame;
|
||||
@ -771,9 +771,6 @@ namespace Aurora::Console::ConsoleWxWidgets
|
||||
{
|
||||
if (AuExchange(gConsoleStarted, true)) return;
|
||||
|
||||
gMutex = AuThreadPrimitives::MutexUnique();
|
||||
if (!gMutex) return;
|
||||
|
||||
Aurora::Console::Hooks::AddSubscription(AuUnsafeRaiiToShared(&gConsoleMessageSubscriber));
|
||||
|
||||
gWxWidgetsThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
namespace Aurora::Exit
|
||||
{
|
||||
static AuThreadPrimitives::MutexUnique_t gMutex;
|
||||
static AuThreadPrimitives::Mutex gMutex;
|
||||
static AuList<AuTuple<AuSPtr<IExitSubscriber>, ETriggerLevel>> gTriggerSubscribers;
|
||||
static bool gIsAppRunning {true};
|
||||
|
||||
@ -186,7 +186,6 @@ namespace Aurora::Exit
|
||||
|
||||
void InitExit()
|
||||
{
|
||||
gMutex = AuThreadPrimitives::MutexUnique();
|
||||
InitWatchdog();
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
@ -203,7 +202,5 @@ namespace Aurora::Exit
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
DeinitUnix();
|
||||
#endif
|
||||
|
||||
gMutex.reset();
|
||||
}
|
||||
}
|
@ -31,9 +31,9 @@ namespace Aurora::Grug
|
||||
static const auto kGrugFlushMs = 500;
|
||||
|
||||
static AuThreads::ThreadUnique_t gGrugsBigWorld;
|
||||
static AuThreadPrimitives::ConditionVariableUnique_t gCondVar; // slow logger work queue
|
||||
static AuThreadPrimitives::ConditionMutexUnique_t gMutex; // ^ that
|
||||
static AuThreadPrimitives::SemaphoreUnique_t gArrows;
|
||||
static AuThreadPrimitives::ConditionMutex gMutex; // ^ that
|
||||
static AuThreadPrimitives::ConditionVariable gCondVar(AuUnsafeRaiiToShared(gMutex.AsPointer())); // slow logger work queue
|
||||
static AuThreadPrimitives::Semaphore gArrows;
|
||||
|
||||
static void SlowStartupTasks()
|
||||
{
|
||||
@ -130,16 +130,6 @@ namespace Aurora::Grug
|
||||
|
||||
void InitGrug()
|
||||
{
|
||||
gMutex = AuThreadPrimitives::ConditionMutexUnique();
|
||||
SysAssert(gMutex, "Couldn't allocate a unique condition variable mutex for grug");
|
||||
|
||||
auto shared = AuUnsafeRaiiToShared(gMutex);
|
||||
gCondVar = AuThreadPrimitives::ConditionVariableUnique(shared);
|
||||
SysAssert(gCondVar, "Couldn't allocate a unique condition variable for grug");
|
||||
|
||||
gArrows = AuThreadPrimitives::SemaphoreUnique();
|
||||
SysAssert(gArrows, "Couldn't allocate an arrow counter for grug");
|
||||
|
||||
InitFlushThread();
|
||||
}
|
||||
|
||||
@ -152,10 +142,6 @@ namespace Aurora::Grug
|
||||
|
||||
GrugFlushWrites();
|
||||
GrugFlushFlushs();
|
||||
|
||||
gMutex.reset();
|
||||
gCondVar.reset();
|
||||
gArrows.reset();
|
||||
|
||||
DeinitArrows();
|
||||
}
|
||||
|
@ -15,12 +15,9 @@ namespace Aurora::IO
|
||||
{
|
||||
bool IOProcessorItems::Init()
|
||||
{
|
||||
this->mutex = AuThreadPrimitives::CriticalSectionUnique();
|
||||
this->mutex2 = AuThreadPrimitives::CriticalSectionUnique();
|
||||
|
||||
this->cvEvent = AuLoop::NewLSEvent(false, true, true);
|
||||
|
||||
return bool(this->mutex) && bool(this->mutex2);
|
||||
return bool(this->cvEvent);
|
||||
}
|
||||
|
||||
bool IOProcessorItems::AddFrameTemp(const AuSPtr<IOProcessorItem> &item)
|
||||
|
@ -22,9 +22,9 @@ namespace Aurora::IO
|
||||
|
||||
AuList<AuSPtr<IOProcessorItem>> registeredIO;
|
||||
|
||||
AuThreadPrimitives::CriticalSectionUnique_t mutex;
|
||||
AuThreadPrimitives::CriticalSection mutex;
|
||||
AuList<AuSPtr<IOProcessorItem>> workSignaled;
|
||||
AuThreadPrimitives::CriticalSectionUnique_t mutex2;
|
||||
AuThreadPrimitives::CriticalSection mutex2;
|
||||
AuList<AuSPtr<IOProcessorItem>> workSignaled2;
|
||||
|
||||
AuList<AuSPtr<IOProcessorItem>> finalizeQueue;
|
||||
|
@ -123,7 +123,10 @@ namespace Aurora::IO::FS
|
||||
SysPanic("Couldn't get known special directory path of [MS:{}-{}-{}-{}{}{}{}{}{}{}{}] with a NULL access token",
|
||||
rfid.Data1, rfid.Data2, rfid.Data3, rfid.Data4[0], rfid.Data4[1], rfid.Data4[2], rfid.Data4[3], rfid.Data4[4], rfid.Data4[5], rfid.Data4[6], rfid.Data4[7]);
|
||||
}
|
||||
return Locale::ConvertFromWChar(directory);
|
||||
|
||||
auto ret = Locale::ConvertFromWChar(directory);
|
||||
CoTaskMemFree(directory);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void SetNamespaceDirectories()
|
||||
@ -300,10 +303,22 @@ namespace Aurora::IO::FS
|
||||
|
||||
void InitResources()
|
||||
{
|
||||
DeinitResources();
|
||||
SetNamespaceDirectories();
|
||||
ChangeDir();
|
||||
}
|
||||
|
||||
void DeinitResources()
|
||||
{
|
||||
gHomeDirectory.clear();
|
||||
gUserHomeDirectory.clear();
|
||||
gUserWritableAppData.clear();
|
||||
gGlobalWritableAppDirectory.clear();
|
||||
gAdminWritableAppDirectory.clear();
|
||||
gProgramsFolder.clear();
|
||||
gApplicationData.clear();
|
||||
}
|
||||
|
||||
AUKN_SYM bool GetAppData(AuString &path)
|
||||
{
|
||||
path.clear();
|
||||
|
@ -13,6 +13,7 @@ namespace Aurora::IO::FS
|
||||
AuOptional<AuString> GetSystemLibPath();
|
||||
AuOptional<AuString> GetUserLibPath2();
|
||||
AuOptional<AuString> GetSystemLibPath2();
|
||||
|
||||
|
||||
void InitResources();
|
||||
void DeinitResources();
|
||||
}
|
@ -13,13 +13,12 @@ namespace Aurora::IO::Net
|
||||
{
|
||||
NetSrvWorkers::NetSrvWorkers()
|
||||
{
|
||||
this->pCondVar_ = AuThreadPrimitives::CriticalSectionUnique();
|
||||
SysAssert(this->pCondVar_);
|
||||
|
||||
}
|
||||
|
||||
AuSPtr<INetWorker> NetSrvWorkers::Attach(const AuSPtr<IIOProcessor> &processor)
|
||||
{
|
||||
AU_LOCK_GUARD(this->spinLock_);
|
||||
AU_LOCK_GUARD(this->mutex_);
|
||||
auto worker = AuMakeShared<NetWorker>(this,
|
||||
this->workerPool_.size(),
|
||||
processor);
|
||||
@ -45,7 +44,7 @@ namespace Aurora::IO::Net
|
||||
|
||||
void NetSrvWorkers::RemoveCache(NetWorker *worker)
|
||||
{
|
||||
AU_LOCK_GUARD(this->spinLock_);
|
||||
AU_LOCK_GUARD(this->mutex_);
|
||||
for (AuUInt i = 0;
|
||||
i < this->workerPool_.size();
|
||||
i++)
|
||||
@ -63,7 +62,7 @@ namespace Aurora::IO::Net
|
||||
|
||||
AuSPtr<NetWorker> NetSrvWorkers::GetWorkerByIndex(AuUInt index)
|
||||
{
|
||||
AU_LOCK_GUARD(this->spinLock_);
|
||||
AU_LOCK_GUARD(this->mutex_);
|
||||
return this->workerPool_[index % this->workerPool_.size()];
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,7 @@ namespace Aurora::IO::Net
|
||||
AuSPtr<INetWorker> GetWorkerByIndexSafe(AuUInt index) override;
|
||||
|
||||
private:
|
||||
AuThreadPrimitives::CriticalSectionUnique_t pCondVar_;
|
||||
AuList<AuSPtr<NetWorker>> workerPool_;
|
||||
AuThreadPrimitives::SpinLock spinLock_;
|
||||
AuThreadPrimitives::Mutex mutex_;
|
||||
};
|
||||
}
|
@ -45,8 +45,7 @@ namespace Aurora::IO::Net
|
||||
|
||||
bool NetDatagramSocketServer::Init()
|
||||
{
|
||||
this->mutex_ = AuThreadPrimitives::MutexUnique();
|
||||
return bool(this->mutex_);
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetDatagramSocketServer::Start(const NetEndpoint &local)
|
||||
|
@ -81,6 +81,6 @@ namespace Aurora::IO::Net
|
||||
AuSPtr<IDatagramServer> pDatagramServer_;
|
||||
AuSPtr<ISocketDriverFactory> pSocketDriverFactory_;
|
||||
NetDatagramSocketEviction eviction;
|
||||
AuThreadPrimitives::MutexUnique_t mutex_;
|
||||
AuThreadPrimitives::Mutex mutex_;
|
||||
};
|
||||
}
|
@ -19,9 +19,8 @@ namespace Aurora::Logging::Sinks
|
||||
|
||||
bool FIOSink::Init()
|
||||
{
|
||||
this->logMutex_ = AuThreadPrimitives::MutexUnique();
|
||||
this->file_ = AuIOFS::OpenWriteUnique(this->path_);
|
||||
return static_cast<bool>(this->file_) && static_cast<bool>(this->logMutex_);
|
||||
return static_cast<bool>(this->file_);
|
||||
}
|
||||
|
||||
void FIOSink::OnMessageBlocking(AuUInt8 uLevel, const ConsoleMessage &msg)
|
||||
|
@ -26,7 +26,7 @@ namespace Aurora::Logging::Sinks
|
||||
AuIOFS::OpenWriteUnique_t file_;
|
||||
bool bBinary_;
|
||||
AuByteBuffer logBuffer_;
|
||||
AuThreadPrimitives::MutexUnique_t logMutex_;
|
||||
AuThreadPrimitives::Mutex logMutex_;
|
||||
ADD_FORMATTER_CONTAINER;
|
||||
};
|
||||
|
||||
|
@ -17,8 +17,7 @@ namespace Aurora::Logging::Sinks
|
||||
|
||||
bool IPCSink::Init()
|
||||
{
|
||||
this->logMutex_ = AuThreadPrimitives::MutexUnique();
|
||||
return static_cast<bool>(this->pipe_) && static_cast<bool>(this->logMutex_);
|
||||
return static_cast<bool>(this->pipe_);
|
||||
}
|
||||
|
||||
AuSPtr<IO::IPC::IPCPipe> IPCSink::ToPipe()
|
||||
|
@ -24,7 +24,7 @@ namespace Aurora::Logging::Sinks
|
||||
private:
|
||||
AuSPtr<Aurora::IO::IPC::IPCPipe> pipe_;
|
||||
AuByteBuffer logBuffer_;
|
||||
AuThreadPrimitives::MutexUnique_t logMutex_;
|
||||
AuThreadPrimitives::Mutex logMutex_;
|
||||
bool lengthPrefixed_;
|
||||
};
|
||||
|
||||
|
@ -17,9 +17,8 @@ namespace Aurora::Logging::Sinks
|
||||
|
||||
bool RingBufferSink::Init()
|
||||
{
|
||||
this->logMutex_ = AuThreadPrimitives::MutexUnique();
|
||||
this->logBuffer_.reserve(maxCount_);
|
||||
return static_cast<bool>(this->logMutex_);
|
||||
AuTryReserve(this->logBuffer_, this->maxCount_);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RingBufferSink::OnMessageBlocking(AuUInt8 level, const ConsoleMessage &msg)
|
||||
|
@ -27,7 +27,7 @@ namespace Aurora::Logging::Sinks
|
||||
AuUInt32 maxCount_;
|
||||
AuUInt32 index_;
|
||||
AuList<ConsoleMessage> logBuffer_;
|
||||
AuThreadPrimitives::MutexUnique_t logMutex_;
|
||||
AuThreadPrimitives::Mutex logMutex_;
|
||||
};
|
||||
|
||||
void NewRingBufferRelease(IBasicSink *logger);
|
||||
|
@ -57,7 +57,7 @@ namespace Aurora::Memory
|
||||
{
|
||||
virtual AuSPtr<Heap> AllocateDivision(AuUInt32 heap, AuUInt32 alignment) override;
|
||||
|
||||
InternalHeap() : mutex_(nullptr), heap_(nullptr), count_(0)
|
||||
InternalHeap() : heap_(nullptr), count_(0)
|
||||
{ }
|
||||
|
||||
virtual ~InternalHeap();
|
||||
@ -99,7 +99,7 @@ namespace Aurora::Memory
|
||||
|
||||
private:
|
||||
|
||||
AuThreadPrimitives::MutexUnique_t mutex_;
|
||||
AuThreadPrimitives::Mutex mutex_;
|
||||
|
||||
O1HeapInstance *heap_ {};
|
||||
int count_ {};
|
||||
@ -146,21 +146,15 @@ namespace Aurora::Memory
|
||||
this->base_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
this->mutex_.reset();
|
||||
}
|
||||
|
||||
bool InternalHeap::Init(AuUInt length, void *ptr)
|
||||
{
|
||||
SysAssert(!this->base_, "heap already initialized");
|
||||
SysAssert(!this->mutex_, "heap already initialized");
|
||||
|
||||
SysAssert(length, "invalid heap allocation");
|
||||
this->length_ = length;
|
||||
|
||||
this->mutex_ = AuThreadPrimitives::MutexUnique();
|
||||
if (!this->mutex_) return false;
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
this->base_ = ptr;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace Aurora::Process
|
||||
{
|
||||
static AuThreadPrimitives::MutexUnique_t gMutex;
|
||||
static AuThreadPrimitives::Mutex gMutex;
|
||||
static AuBST<AuUInt, AuString> gPathCache;
|
||||
static AuBST<AuUInt, AuString> gModNameCache;
|
||||
|
||||
@ -311,11 +311,9 @@ namespace Aurora::Process
|
||||
|
||||
void InitProcessMapNt()
|
||||
{
|
||||
gMutex = AuThreadPrimitives::MutexUnique();
|
||||
}
|
||||
|
||||
void DeinitProcessMapNt()
|
||||
{
|
||||
gMutex.reset();
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@ namespace Aurora::Process
|
||||
static const auto kMinPageAlignment = 4096;
|
||||
static const auto kPageBufferPad = 20;
|
||||
|
||||
static AuThreadPrimitives::MutexUnique_t gMutexUnique;
|
||||
static AuThreadPrimitives::Mutex gMutexUnique;
|
||||
static AuHashMap<ModuleBasePair,
|
||||
AuSPtr<PublicModule>,
|
||||
ModuleBasePairHash, // TODO: this precede auhashcode
|
||||
@ -175,8 +175,6 @@ namespace Aurora::Process
|
||||
|
||||
void InitProcessMap()
|
||||
{
|
||||
gMutexUnique = AuThreadPrimitives::MutexUnique();
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
InitProcessMapNt();
|
||||
#endif
|
||||
@ -202,8 +200,6 @@ namespace Aurora::Process
|
||||
|
||||
void DeinitProcessMap()
|
||||
{
|
||||
gMutexUnique.reset();
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
DeinitProcessMapNt();
|
||||
#endif
|
||||
|
@ -19,8 +19,8 @@
|
||||
namespace Aurora::Processes
|
||||
{
|
||||
static AuList<AuString> gOpenItems;
|
||||
static AuThreadPrimitives::ConditionMutexUnique_t gCondMutex;
|
||||
static AuThreadPrimitives::ConditionVariableUnique_t gCondVariable;
|
||||
static AuThreadPrimitives::ConditionMutex gCondMutex;
|
||||
static AuThreadPrimitives::ConditionVariable gCondVariable(AuUnsafeRaiiToShared(gCondMutex.AsPointer()));
|
||||
static AuThreads::ThreadUnique_t gOpenerThread;
|
||||
|
||||
static void RunTasks()
|
||||
@ -62,12 +62,6 @@ namespace Aurora::Processes
|
||||
|
||||
void InitWin32Opener()
|
||||
{
|
||||
gCondMutex = AuThreadPrimitives::ConditionMutexUnique();
|
||||
SysAssert(gCondMutex);
|
||||
|
||||
gCondVariable = AuThreadPrimitives::ConditionVariableUnique(AuUnsafeRaiiToShared(gCondMutex));
|
||||
SysAssert(gCondVariable);
|
||||
|
||||
gOpenerThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
|
||||
AuMakeShared<AuThreads::IThreadVectorsFunctional>(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(OpenerThread)),
|
||||
AuThreads::IThreadVectorsFunctional::OnExit_t{}),
|
||||
@ -83,8 +77,6 @@ namespace Aurora::Processes
|
||||
gOpenerThread->SendExitSignal();
|
||||
gCondVariable->Broadcast();
|
||||
gOpenerThread.reset();
|
||||
gCondVariable.reset();
|
||||
gCondMutex.reset();
|
||||
}
|
||||
|
||||
AUKN_SYM void OpenUri(const AuString &uri)
|
||||
|
Loading…
Reference in New Issue
Block a user