aboutsummaryrefslogtreecommitdiff
path: root/zencore/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zencore/thread.cpp')
-rw-r--r--zencore/thread.cpp197
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