diff options
Diffstat (limited to 'zencore/thread.cpp')
| -rw-r--r-- | zencore/thread.cpp | 197 |
1 files changed, 98 insertions, 99 deletions
diff --git a/zencore/thread.cpp b/zencore/thread.cpp index f1decf9a5..6d17e6968 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -122,22 +122,22 @@ RwLock::ReleaseExclusive() struct EventInner { std::mutex Mutex; - std::condition_variable CondVar; - bool volatile bSet = false; + std::condition_variable CondVar; + bool volatile bSet = false; }; -#endif // !ZEN_PLATFORM_WINDOWS +#endif // !ZEN_PLATFORM_WINDOWS Event::Event() { - bool bManualReset = true; + bool bManualReset = true; bool bInitialState = false; #if ZEN_PLATFORM_WINDOWS m_EventHandle = CreateEvent(nullptr, bManualReset, bInitialState, nullptr); #else ZEN_UNUSED(bManualReset); - auto* Inner = new EventInner(); - Inner->bSet = bInitialState; + auto* Inner = new EventInner(); + Inner->bSet = bInitialState; m_EventHandle = Inner; #endif } @@ -153,7 +153,7 @@ Event::Set() #if ZEN_PLATFORM_WINDOWS SetEvent(m_EventHandle); #else - auto* Inner = (EventInner*)m_EventHandle; + auto* Inner = (EventInner*)m_EventHandle; { std::unique_lock Lock(Inner->Mutex); Inner->bSet = true; @@ -216,11 +216,7 @@ Event::Wait(int TimeoutMs) return true; } - return Inner->CondVar.wait_for( - Lock, - std::chrono::milliseconds(TimeoutMs), - [&] { return Inner->bSet; } - ); + return Inner->CondVar.wait_for(Lock, std::chrono::milliseconds(TimeoutMs), [&] { return Inner->bSet; }); } std::unique_lock Lock(Inner->Mutex); @@ -237,16 +233,15 @@ Event::Wait(int TimeoutMs) ////////////////////////////////////////////////////////////////////////// #if ZEN_PLATFORM_LINUX -static bool IsMessageQueueEmpty(int Fd) +static bool +IsMessageQueueEmpty(int Fd) { // Check if there is already a message in the queue. - mq_attr Attributes = { O_NONBLOCK, 1, 1, 0 }; + mq_attr Attributes = {O_NONBLOCK, 1, 1, 0}; mq_getattr(Fd, &Attributes); return (Attributes.mq_curmsgs == 0); } -#endif // ZEN_PLATFORM_LINUX - - +#endif // ZEN_PLATFORM_LINUX NamedEvent::NamedEvent(std::string_view EventName) { @@ -264,19 +259,19 @@ NamedEvent::NamedEvent(std::string_view EventName) Name << EventName; mq_attr Attributes = { - 0, // flags - 1, // max message count - 1, // max message size - 0, // current messages + 0, // flags + 1, // max message count + 1, // max message size + 0, // current messages }; - int Inner = mq_open(Name.c_str(), O_RDWR|O_CREAT|O_CLOEXEC, 0644, &Attributes); + int Inner = mq_open(Name.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0644, &Attributes); if (Inner < 0) { ThrowLastError("Failed to get message queue from mq_open()"); } - int LockResult = flock(Inner, LOCK_EX|LOCK_NB); + int LockResult = flock(Inner, LOCK_EX | LOCK_NB); if (LockResult == 0) { // This is really thread safe as the message queue could be set between @@ -300,7 +295,8 @@ NamedEvent::~NamedEvent() Close(); } -void NamedEvent::Close() +void +NamedEvent::Close() { if (m_EventHandle == nullptr) { @@ -310,11 +306,11 @@ void NamedEvent::Close() #if ZEN_PLATFORM_WINDOWS CloseHandle(m_EventHandle); #elif ZEN_PLATFORM_LINUX - int Inner = int(intptr_t(m_EventHandle)); + int Inner = int(intptr_t(m_EventHandle)); - if (flock(Inner, LOCK_EX|LOCK_NB) == 0) + if (flock(Inner, LOCK_EX | LOCK_NB) == 0) { - flock(Inner, LOCK_UN|LOCK_NB); + flock(Inner, LOCK_UN | LOCK_NB); std::filesystem::path Name = PathFromHandle((void*)(intptr_t(Inner))); mq_unlink(Name.c_str()); } @@ -325,7 +321,8 @@ void NamedEvent::Close() m_EventHandle = nullptr; } -void NamedEvent::Set() +void +NamedEvent::Set() { #if ZEN_PLATFORM_WINDOWS SetEvent(m_EventHandle); @@ -345,7 +342,8 @@ void NamedEvent::Set() #endif } -bool NamedEvent::Wait(int TimeoutMs) +bool +NamedEvent::Wait(int TimeoutMs) { #if ZEN_PLATFORM_WINDOWS const DWORD Timeout = (TimeoutMs < 0) ? INFINITE : TimeoutMs; @@ -368,7 +366,7 @@ bool NamedEvent::Wait(int TimeoutMs) } struct timeval TimeoutValue = { - .tv_sec = 0, + .tv_sec = 0, .tv_usec = TimeoutMs << 10, }; struct timeval* TimeoutPtr = (TimeoutMs < 0) ? nullptr : &TimeoutValue; @@ -415,7 +413,7 @@ NamedMutex::Create(std::string_view MutexName) ExtendableStringBuilder<64> Name; Name << "/tmp/" << MutexName; - int Inner = open(Name.c_str(), O_RDWR|O_CREAT|O_CLOEXEC, 0644); + int Inner = open(Name.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0644); if (Inner < 0) { return false; @@ -430,7 +428,7 @@ NamedMutex::Create(std::string_view MutexName) m_MutexHandle = (void*)(intptr_t(Inner)); return true; -#endif // ZEN_PLATFORM_WINDOWS +#endif // ZEN_PLATFORM_WINDOWS } bool @@ -458,12 +456,12 @@ NamedMutex::Exists(std::string_view MutexName) Name << "/tmp/" << MutexName; bool bExists = false; - int Fd = open(Name.c_str(), O_RDWR, 0644); + int Fd = open(Name.c_str(), O_RDWR, 0644); if (Fd >= 0) { - if (flock(Fd, LOCK_EX|LOCK_NB) == 0) + if (flock(Fd, LOCK_EX | LOCK_NB) == 0) { - flock(Fd, LOCK_UN|LOCK_NB); + flock(Fd, LOCK_UN | LOCK_NB); } else { @@ -473,7 +471,7 @@ NamedMutex::Exists(std::string_view MutexName) } return bExists; -#endif // ZEN_PLATFORM_WINDOWS +#endif // ZEN_PLATFORM_WINDOWS } ////////////////////////////////////////////////////////////////////////// @@ -495,7 +493,7 @@ ProcessHandle::Initialize(void* ProcessHandle) m_ProcessHandle = ProcessHandle; m_Pid = GetProcessId(m_ProcessHandle); } -#endif // ZEN_PLATFORM_WINDOWS +#endif // ZEN_PLATFORM_WINDOWS ProcessHandle::~ProcessHandle() { @@ -566,10 +564,10 @@ ProcessHandle::Terminate(int ExitCode) #if ZEN_PLATFORM_WINDOWS TerminateProcess(m_ProcessHandle, ExitCode); DWORD WaitResult = WaitForSingleObject(m_ProcessHandle, INFINITE); - bSuccess = (WaitResult != WAIT_OBJECT_0); + bSuccess = (WaitResult != WAIT_OBJECT_0); #elif ZEN_PLATFORM_LINUX ZEN_UNUSED(ExitCode); - bSuccess = (kill(m_Pid, SIGKILL) == 0); + bSuccess = (kill(m_Pid, SIGKILL) == 0); #else # error Check kill() on this platform #endif @@ -589,7 +587,7 @@ ProcessHandle::Reset() CloseHandle(m_ProcessHandle); #endif m_ProcessHandle = nullptr; - m_Pid = 0; + m_Pid = 0; } } @@ -615,12 +613,12 @@ ProcessHandle::Wait(int TimeoutMs) break; } #elif ZEN_PLATFORM_LINUX - const int SleepMs = 20; - timespec SleepTime = { 0, SleepMs * 1000 * 1000 }; - for (int i = 0; ; i += SleepMs) + const int SleepMs = 20; + timespec SleepTime = {0, SleepMs * 1000 * 1000}; + for (int i = 0;; i += SleepMs) { int WaitState = 0; - waitpid(m_Pid, &WaitState, WNOHANG|WCONTINUED|WUNTRACED); + waitpid(m_Pid, &WaitState, WNOHANG | WCONTINUED | WUNTRACED); if (kill(m_Pid, 0) < 0) { @@ -649,13 +647,15 @@ ProcessHandle::Wait(int TimeoutMs) ////////////////////////////////////////////////////////////////////////// #if !ZEN_PLATFORM_WINDOWS || ZEN_WITH_TESTS -static void BuildArgV(std::vector<char*>& Out, char* CommandLine) +static void +BuildArgV(std::vector<char*>& Out, char* CommandLine) { char* Cursor = CommandLine; while (true) { // Skip leading whitespace - for (; *Cursor == ' '; ++Cursor); + for (; *Cursor == ' '; ++Cursor) + ; // Check for nullp terminator if (*Cursor == '\0') @@ -675,8 +675,7 @@ static void BuildArgV(std::vector<char*>& Out, char* CommandLine) break; } ++Cursor; - } - while (*Cursor != '\0'); + } while (*Cursor != '\0'); if (*Cursor == '\0') { @@ -687,13 +686,11 @@ static void BuildArgV(std::vector<char*>& Out, char* CommandLine) ++Cursor; } } -#endif // !WINDOWS || TESTS +#endif // !WINDOWS || TESTS #if ZEN_PLATFORM_WINDOWS -static CreateProcResult CreateProcNormal( - const std::filesystem::path& Executable, - std::string_view CommandLine, - const CreateProcOptions& Options) +static CreateProcResult +CreateProcNormal(const std::filesystem::path& Executable, std::string_view CommandLine, const CreateProcOptions& Options) { PROCESS_INFORMATION ProcessInfo{}; STARTUPINFO StartupInfo{.cb = sizeof(STARTUPINFO)}; @@ -738,10 +735,8 @@ static CreateProcResult CreateProcNormal( return ProcessInfo.hProcess; } -static CreateProcResult CreateProcUnelevated( - const std::filesystem::path& Executable, - std::string_view CommandLine, - const CreateProcOptions& Options) +static CreateProcResult +CreateProcUnelevated(const std::filesystem::path& Executable, std::string_view CommandLine, const CreateProcOptions& Options) { /* Launches a binary with the shell as its parent. The shell (such as Explorer) should be an unelevated process. */ @@ -775,15 +770,15 @@ static CreateProcResult CreateProcUnelevated( InitializeProcThreadAttributeList(nullptr, 1, 0, &AttrListSize); auto AttrList = (PPROC_THREAD_ATTRIBUTE_LIST)malloc(AttrListSize); - auto $1 = MakeGuard([&] { free(AttrList); }); + auto $1 = MakeGuard([&] { free(AttrList); }); if (!InitializeProcThreadAttributeList(AttrList, 1, 0, &AttrListSize)) { return nullptr; } - BOOL bOk = UpdateProcThreadAttribute(AttrList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, - (HANDLE*)&Process, sizeof(Process), nullptr, nullptr); + BOOL bOk = + UpdateProcThreadAttribute(AttrList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, (HANDLE*)&Process, sizeof(Process), nullptr, nullptr); if (!bOk) { return nullptr; @@ -804,7 +799,7 @@ static CreateProcResult CreateProcUnelevated( // Everything is set up now so we can proceed and launch the process STARTUPINFOEXW StartupInfo = { - .StartupInfo = { .cb = sizeof(STARTUPINFOEXW) }, + .StartupInfo = {.cb = sizeof(STARTUPINFOEXW)}, .lpAttributeList = AttrList, }; PROCESS_INFORMATION ProcessInfo = {}; @@ -817,9 +812,16 @@ static CreateProcResult CreateProcUnelevated( ExtendableWideStringBuilder<256> CommandLineZ; CommandLineZ << CommandLine; - bOk = CreateProcessW(Executable.c_str(), CommandLineZ.Data(), nullptr, nullptr, - FALSE, CreateProcFlags, nullptr, nullptr, &StartupInfo.StartupInfo, - &ProcessInfo); + bOk = CreateProcessW(Executable.c_str(), + CommandLineZ.Data(), + nullptr, + nullptr, + FALSE, + CreateProcFlags, + nullptr, + nullptr, + &StartupInfo.StartupInfo, + &ProcessInfo); if (bOk == FALSE) { return nullptr; @@ -829,10 +831,8 @@ static CreateProcResult CreateProcUnelevated( return ProcessInfo.hProcess; } -static CreateProcResult CreateProcElevated( - const std::filesystem::path& Executable, - std::string_view CommandLine, - const CreateProcOptions& Options) +static CreateProcResult +CreateProcElevated(const std::filesystem::path& Executable, std::string_view CommandLine, const CreateProcOptions& Options) { ExtendableWideStringBuilder<256> CommandLineZ; CommandLineZ << CommandLine; @@ -858,12 +858,10 @@ static CreateProcResult CreateProcElevated( return nullptr; } -#endif // ZEN_PLATFORM_WINDOWS +#endif // ZEN_PLATFORM_WINDOWS -CreateProcResult CreateProc( - const std::filesystem::path& Executable, - std::string_view CommandLine, - const CreateProcOptions& Options) +CreateProcResult +CreateProc(const std::filesystem::path& Executable, std::string_view CommandLine, const CreateProcOptions& Options) { #if ZEN_PLATFORM_WINDOWS if (Options.Flags & CreateProcOptions::Flag_Unelevated) @@ -879,7 +877,7 @@ CreateProcResult CreateProc( return CreateProcNormal(Executable, CommandLine, Options); #else std::vector<char*> ArgV; - std::string CommandLineZ(CommandLine); + std::string CommandLineZ(CommandLine); BuildArgV(ArgV, CommandLineZ.data()); ArgV.push_back(nullptr); @@ -946,7 +944,7 @@ ProcessMonitor::IsRunning() CloseHandle(Proc); } #else - int Pid = int(intptr_t(Proc)); + int Pid = int(intptr_t(Proc)); ProcIsActive = IsProcessRunning(Pid); #endif @@ -1075,31 +1073,32 @@ TEST_CASE("Thread") TEST_CASE("BuildArgV") { - const char* Words[] = { "one", "two", "three", "four", "five" }; - struct { + const char* Words[] = {"one", "two", "three", "four", "five"}; + struct + { int WordCount; const char* Input; } Cases[] = { - { 0, "" }, - { 0, " " }, - { 1, "one" }, - { 1, " one" }, - { 1, "one " }, - { 2, "one two" }, - { 2, " one two" }, - { 2, "one two " }, - { 2, " one two" }, - { 2, "one two " }, - { 2, "one two " }, - { 3, "one two three" }, - { 3, "\"one\" two \"three\"" }, - { 5, "one two three four five" }, + {0, ""}, + {0, " "}, + {1, "one"}, + {1, " one"}, + {1, "one "}, + {2, "one two"}, + {2, " one two"}, + {2, "one two "}, + {2, " one two"}, + {2, "one two "}, + {2, "one two "}, + {3, "one two three"}, + {3, "\"one\" two \"three\""}, + {5, "one two three four five"}, }; for (const auto& Case : Cases) { std::vector<char*> OutArgs; - StringBuilder<64> Mutable; + StringBuilder<64> Mutable; Mutable << Case.Input; BuildArgV(OutArgs, Mutable.Data()); @@ -1107,11 +1106,11 @@ TEST_CASE("BuildArgV") for (int i = 0, n = int(OutArgs.size()); i < n; ++i) { - const char* Truth = Words[i]; - size_t TruthLen = strlen(Truth); + const char* Truth = Words[i]; + size_t TruthLen = strlen(Truth); const char* Candidate = OutArgs[i]; - bool bQuoted = (Candidate[0] == '\"'); + bool bQuoted = (Candidate[0] == '\"'); Candidate += bQuoted; CHECK(strncmp(Truth, Candidate, TruthLen) == 0); @@ -1127,7 +1126,7 @@ TEST_CASE("BuildArgV") TEST_CASE("NamedEvent") { std::string Name = "zencore_test_event"; - NamedEvent TestEvent(Name); + NamedEvent TestEvent(Name); // Timeout test for (uint32_t i = 0; i < 8; ++i) @@ -1135,9 +1134,9 @@ TEST_CASE("NamedEvent") bool bEventSet = TestEvent.Wait(100); CHECK(!bEventSet); } - + // Thread check - std::thread Waiter = std::thread([Name] () { + std::thread Waiter = std::thread([Name]() { NamedEvent ReadyEvent(Name + "_ready"); ReadyEvent.Set(); @@ -1176,6 +1175,6 @@ TEST_CASE("NamedMutex") CHECK(!NamedMutex::Exists(Name)); } -#endif // ZEN_WITH_TESTS +#endif // ZEN_WITH_TESTS } // namespace zen |