From a38633c4534ccd58e285629562f8eadd4662aab8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 16 Mar 2026 23:03:02 +0100 Subject: [PATCH] Add basic `WebThread` impl --- Source/Engine/Platform/Web/WebPlatform.cpp | 23 ++++++++++ Source/Engine/Platform/Web/WebThread.h | 53 ++++++++++++++++++---- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Platform/Web/WebPlatform.cpp b/Source/Engine/Platform/Web/WebPlatform.cpp index cd814af9c..d76ec7dd9 100644 --- a/Source/Engine/Platform/Web/WebPlatform.cpp +++ b/Source/Engine/Platform/Web/WebPlatform.cpp @@ -3,6 +3,7 @@ #if PLATFORM_WEB #include "WebPlatform.h" +#include "WebThread.h" #include "WebFileSystem.h" #include "Engine/Core/Log.h" #include "Engine/Core/Types/String.h" @@ -50,6 +51,28 @@ DialogResult MessageBox::Show(Window* parent, const StringView& text, const Stri return DialogResult::None; } +WebThread* WebThread::Create(IRunnable* runnable, const String& name, ThreadPriority priority, uint32 stackSize) +{ +#ifdef __EMSCRIPTEN_PTHREADS__ + pthread_attr_t attr; + pthread_attr_init(&attr); + if (stackSize != 0) + pthread_attr_setstacksize(&attr, stackSize); + auto thread = New(runnable, name, priority); + const int result = pthread_create(&thread->_thread, &attr, ThreadProc, thread); + if (result != 0) + { + LOG(Warning, "Failed to spawn a thread. Result code: {0}", result); + Delete(thread); + return nullptr; + } + return thread; +#else + LOG(Fatal, "Threading is not supported."); + return nullptr; +#endif +} + void WebFileSystem::GetSpecialFolderPath(const SpecialFolder type, String& result) { result = TEXT("/"); diff --git a/Source/Engine/Platform/Web/WebThread.h b/Source/Engine/Platform/Web/WebThread.h index a5086787b..926567182 100644 --- a/Source/Engine/Platform/Web/WebThread.h +++ b/Source/Engine/Platform/Web/WebThread.h @@ -5,6 +5,10 @@ #if PLATFORM_WEB #include "../Base/ThreadBase.h" +#ifdef __EMSCRIPTEN_PTHREADS__ +#include +#include +#endif /// /// Thread object for Web platform. @@ -20,6 +24,9 @@ public: /// The thread priority. WebThread(IRunnable* runnable, const String& name, ThreadPriority priority) : ThreadBase(runnable, name, priority) +#ifdef __EMSCRIPTEN_PTHREADS__ + , _thread(0) +#endif { } @@ -32,32 +39,60 @@ public: /// Tells the thread whether it needs to adjust its priority or not. Defaults to normal priority /// The size of the stack to create. 0 means use the current thread's stack size /// Pointer to the new thread or null if cannot create it - static WebThread* Create(IRunnable* runnable, const String& name, ThreadPriority priority = ThreadPriority::Normal, uint32 stackSize = 0) - { - return New(runnable, name, priority); - } + static WebThread* Create(IRunnable* runnable, const String& name, ThreadPriority priority = ThreadPriority::Normal, uint32 stackSize = 0); -public: +#ifdef __EMSCRIPTEN_PTHREADS__ // [ThreadBase] void Join() override { - // TOOD: impl this + pthread_join(_thread, nullptr); + ClearHandleInternal(); } protected: // [ThreadBase] void ClearHandleInternal() override { - // TOOD: impl this + _thread = 0; } void SetPriorityInternal(ThreadPriority priority) override { - // TOOD: impl this + // Not supported } void KillInternal(bool waitForJoin) override { - // TOOD: impl this + if (waitForJoin) + pthread_join(_thread, nullptr); + pthread_kill(_thread, SIGKILL); } + +private: + pthread_t _thread; + + static void* ThreadProc(void* pThis) + { + auto thread = (WebThread*)pThis; + const int32 exitCode = thread->Run(); + return (void*)(uintptr)exitCode; + } +#else + // [ThreadBase] + void Join() override + { + } + +protected: + // [ThreadBase] + void ClearHandleInternal() override + { + } + void SetPriorityInternal(ThreadPriority priority) override + { + } + void KillInternal(bool waitForJoin) override + { + } +#endif }; #endif