From 61fe958584165172e5340256d19814f71b10dad4 Mon Sep 17 00:00:00 2001 From: HaseenaSainul <41037131+HaseenaSainul@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:38:07 +0530 Subject: [PATCH 1/4] Handle thunder id based on platform type (#1766) * Use JSON::InstanceID, instead Json::ThreadId thread conversion places * Review comments addressed --------- Co-authored-by: Pierre Wielders --- Source/Thunder/Controller.cpp | 4 ++-- Source/Thunder/Controller.h | 2 +- Source/Thunder/PluginHost.cpp | 11 ++++------- Source/Thunder/PluginServer.h | 7 +------ Source/Thunder/PostMortem.h | 12 ++++++------ Source/core/JSON.h | 1 - Source/core/Portability.cpp | 6 +++--- Source/core/Portability.h | 17 ++++++++-------- Source/core/ProcessInfo.cpp | 12 ++++++------ Source/core/ProcessInfo.h | 6 +++--- Source/core/ResourceMonitor.h | 2 +- Source/core/Thread.cpp | 4 ++-- Source/core/Thread.h | 6 +++--- Source/core/ThreadPool.h | 6 +++--- Source/core/Timer.h | 2 +- Source/core/WorkerPool.h | 8 ++++---- Source/plugins/Metadata.cpp | 4 ++-- Source/plugins/Metadata.h | 30 +++++++++++++++++++++++++++-- Tests/unit/core/test_thread.cpp | 10 +++++----- Tests/unit/core/test_workerpool.cpp | 4 ++-- 20 files changed, 86 insertions(+), 68 deletions(-) diff --git a/Source/Thunder/Controller.cpp b/Source/Thunder/Controller.cpp index f0683b703..04ab088c8 100644 --- a/Source/Thunder/Controller.cpp +++ b/Source/Thunder/Controller.cpp @@ -52,7 +52,7 @@ namespace Plugin { static Core::ProxyPoolType jsonBodyTextFactory(2); - void Controller::Callstack(const ThreadId id, Core::JSON::ArrayType& response) const { + void Controller::Callstack(const Core::thread_id id, Core::JSON::ArrayType& response) const { std::list stackList; ::DumpCallStack(id, stackList); @@ -1256,7 +1256,7 @@ namespace Plugin { while (it.Next() == true) { auto const& entry = it.Current(); - threads.push_back({ entry.Id.Value(), entry.Job.Value(), entry.Runs.Value() }); + threads.push_back({ PluginHost::Metadata::InstanceId(entry.Id.Value()), entry.Job.Value(), entry.Runs.Value() }); } using Iterator = IMetadata::Data::IThreadsIterator; diff --git a/Source/Thunder/Controller.h b/Source/Thunder/Controller.h index bd7ed365a..497e502f4 100644 --- a/Source/Thunder/Controller.h +++ b/Source/Thunder/Controller.h @@ -368,7 +368,7 @@ namespace Plugin { void WorkerPoolMetadata(PluginHost::Metadata::Server& data) const { _pluginServer->WorkerPool().Snapshot(data); } - void Callstack(const ThreadId id, Core::JSON::ArrayType& response) const; + void Callstack(const Core::thread_id id, Core::JSON::ArrayType& response) const; void SubSystems(); uint32_t Clone(const string& basecallsign, const string& newcallsign); void Proxies(Core::JSON::ArrayType& info) const; diff --git a/Source/Thunder/PluginHost.cpp b/Source/Thunder/PluginHost.cpp index be22a0b7a..abbb9c6a7 100644 --- a/Source/Thunder/PluginHost.cpp +++ b/Source/Thunder/PluginHost.cpp @@ -889,11 +889,8 @@ POP_WARNING() printf("Pending: %d\n", static_cast(metaData.Pending.size())); printf("Poolruns:\n"); for (uint8_t index = 0; index < metaData.Slots; index++) { -#ifdef __APPLE__ - printf(" Thread%02d|0x%16" PRIxPTR ": %10d", (index), reinterpret_cast(metaData.Slot[index].WorkerId), metaData.Slot[index].Runs); -#else - printf(" Thread%02d|0x%16lX: %10d", (index), metaData.Slot[index].WorkerId, metaData.Slot[index].Runs); -#endif + printf(" Thread%02d|0x%16" PRIu64 ": %10d", (index), static_cast(Metadata::InstanceId(metaData.Slot[index].WorkerId)), metaData.Slot[index].Runs); + if (metaData.Slot[index].Job.IsSet() == false) { printf("\n"); } @@ -983,10 +980,10 @@ POP_WARNING() case '7': case '8': case '9': { - ThreadId threadId = _dispatcher->WorkerPool().Id(keyPress - '0'); + Core::thread_id threadId = _dispatcher->WorkerPool().Id(keyPress - '0'); printf("\nThreadPool thread[%c] callstack:\n", keyPress); printf("============================================================\n"); - if (threadId != (ThreadId)(~0)) { + if (threadId != (Core::thread_id)(~0)) { uint8_t counter = 0; std::list stackList; ::DumpCallStack(threadId, stackList); diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index df783746f..5614b66b9 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -4600,12 +4600,7 @@ namespace PluginHost { while (index.Next() == true) { std::list stackList; - -#ifdef __APPLE__ - ::DumpCallStack(reinterpret_cast(index.Current().Id.Value()), stackList); -#else - ::DumpCallStack(static_cast(index.Current().Id.Value()), stackList); -#endif + ::DumpCallStack(PluginHost::Metadata::ThreadId(index.Current().Id.Value()), stackList); PostMortemData::Callstack dump; dump.Id = index.Current().Id.Value(); diff --git a/Source/Thunder/PostMortem.h b/Source/Thunder/PostMortem.h index 02d8d6c32..e7167c0bd 100644 --- a/Source/Thunder/PostMortem.h +++ b/Source/Thunder/PostMortem.h @@ -108,10 +108,10 @@ namespace PluginHost { } public: - Core::JSON::Pointer Address; - Core::JSON::String Function; - Core::JSON::String Module; - Core::JSON::DecUInt32 Line; + Core::JSON::InstanceId Address; + Core::JSON::String Function; + Core::JSON::String Module; + Core::JSON::DecUInt32 Line; }; @@ -123,7 +123,7 @@ namespace PluginHost { Callstack() : Core::JSON::Container() - , Id(0) + , Id() , Data() { Add(_T("id"), &Id); Add(_T("stack"), &Data); @@ -145,7 +145,7 @@ namespace PluginHost { ~Callstack() override = default; public: - Core::JSON::Pointer Id; + Core::JSON::InstanceId Id; Core::JSON::ArrayType Data; }; diff --git a/Source/core/JSON.h b/Source/core/JSON.h index 7fd5a4438..d59bfe5c2 100644 --- a/Source/core/JSON.h +++ b/Source/core/JSON.h @@ -1017,7 +1017,6 @@ namespace Core { typedef NumberType OctSInt64; typedef NumberType InstanceId; - typedef InstanceId Pointer; template class FloatType : public IElement, public IMessagePack { diff --git a/Source/core/Portability.cpp b/Source/core/Portability.cpp index f7d5bb83d..49ba11e4f 100644 --- a/Source/core/Portability.cpp +++ b/Source/core/Portability.cpp @@ -147,7 +147,7 @@ static void CallstackSignalHandler(int signr VARIABLE_IS_NOT_USED, siginfo_t* in } } -uint32_t GetCallStack(const ThreadId threadId, void* addresses[], const uint32_t bufferSize) +uint32_t GetCallStack(const Thunder::Core::thread_id threadId, void* addresses[], const uint32_t bufferSize) { uint32_t result = 0; @@ -159,7 +159,7 @@ uint32_t GetCallStack(const ThreadId threadId, void* addresses[], const uint32_t } --result; } - } else if (threadId != (::ThreadId)(~0)) { + } else if (threadId != (Thunder::Core::thread_id)(~0)) { while (std::atomic_exchange_explicit(&g_lock, true, std::memory_order_acquire)) ; // spin until acquired @@ -196,7 +196,7 @@ uint32_t GetCallStack(const ThreadId threadId, void* addresses[], const uint32_t extern "C" { -void DumpCallStack(const ThreadId threadId VARIABLE_IS_NOT_USED, std::list& stackList VARIABLE_IS_NOT_USED) +void DumpCallStack(const Thunder::Core::thread_id threadId VARIABLE_IS_NOT_USED, std::list& stackList VARIABLE_IS_NOT_USED) { #if defined(THUNDER_BACKTRACE) void* callstack[32]; diff --git a/Source/core/Portability.h b/Source/core/Portability.h index add1df3bb..3969ddb11 100644 --- a/Source/core/Portability.h +++ b/Source/core/Portability.h @@ -679,12 +679,6 @@ typedef std::string string; #define STRLEN(STATIC_TEXT) ((sizeof(STATIC_TEXT) / sizeof(TCHAR)) - 1) #define EMPTY_STRING _T("") -#ifdef __LINUX__ -typedef pthread_t ThreadId; -#else -typedef DWORD ThreadId; -#endif - #define QUOTE(str) #str #define EXPAND_AND_QUOTE(str) QUOTE(str) @@ -717,6 +711,12 @@ namespace Core { #endif #endif + #ifdef __LINUX__ + typedef pthread_t thread_id; + #else + typedef DWORD thread_id; + #endif + typedef uint32_t hresult; struct callstack_info { @@ -990,8 +990,9 @@ EXTERNAL extern int inet_aton(const char* cp, struct in_addr* inp); EXTERNAL extern void usleep(const uint32_t value); #endif -EXTERNAL void DumpCallStack(const ThreadId threadId, std::list& stack); -EXTERNAL uint32_t GetCallStack(const ThreadId threadId, void* addresses[], const uint32_t bufferSize); +void EXTERNAL DumpCallStack(const Thunder::Core::thread_id threadId, std::list& stack); +uint32_t EXTERNAL GetCallStack(const Thunder::Core::thread_id threadId, void* addresses[], const uint32_t bufferSize); + } diff --git a/Source/core/ProcessInfo.cpp b/Source/core/ProcessInfo.cpp index c29dc469a..5d1b071d8 100644 --- a/Source/core/ProcessInfo.cpp +++ b/Source/core/ProcessInfo.cpp @@ -686,30 +686,30 @@ namespace Core { EnumerateChildProcesses(processInfo, _processes); } - bool ProcessTree::ContainsProcess(ThreadId pid) const + bool ProcessTree::ContainsProcess(thread_id pid) const { PUSH_WARNING(DISABLE_WARNING_CONVERSION_TO_GREATERSIZE) - auto comparator = [pid](const ProcessInfo& processInfo) { return ((ThreadId)(processInfo.Id()) == pid); }; + auto comparator = [pid](const ProcessInfo& processInfo) { return ((thread_id)(processInfo.Id()) == pid); }; POP_WARNING() std::list::const_iterator i = std::find_if(_processes.cbegin(), _processes.cend(), comparator); return (i != _processes.cend()); } - void ProcessTree::GetProcessIds(std::list& processIds) const + void ProcessTree::GetProcessIds(std::list& processIds) const { processIds.clear(); for (const ProcessInfo& process : _processes) { PUSH_WARNING(DISABLE_WARNING_CONVERSION_TO_GREATERSIZE) - processIds.push_back((ThreadId)(process.Id())); + processIds.push_back((thread_id)(process.Id())); POP_WARNING() } } - ThreadId ProcessTree::RootId() const + thread_id ProcessTree::RootId() const { PUSH_WARNING(DISABLE_WARNING_CONVERSION_TO_GREATERSIZE) - return (ThreadId)(_processes.front().Id()); + return (thread_id)(_processes.front().Id()); POP_WARNING() } diff --git a/Source/core/ProcessInfo.h b/Source/core/ProcessInfo.h index f87843907..f2807e366 100644 --- a/Source/core/ProcessInfo.h +++ b/Source/core/ProcessInfo.h @@ -414,9 +414,9 @@ namespace Core { public: explicit ProcessTree(const ProcessInfo& processInfo); - bool ContainsProcess(ThreadId pid) const; - void GetProcessIds(std::list& processIds) const; - ThreadId RootId() const; + bool ContainsProcess(thread_id pid) const; + void GetProcessIds(std::list& processIds) const; + thread_id RootId() const; private: std::list _processes; diff --git a/Source/core/ResourceMonitor.h b/Source/core/ResourceMonitor.h index acd6abe95..334747b69 100644 --- a/Source/core/ResourceMonitor.h +++ b/Source/core/ResourceMonitor.h @@ -177,7 +177,7 @@ namespace Core { { return (_monitorRuns); } - ::ThreadId Id() const + thread_id Id() const { return (_monitor != nullptr ? _monitor->Id() : 0); } diff --git a/Source/core/Thread.cpp b/Source/core/Thread.cpp index 690a43af7..b635c20f4 100644 --- a/Source/core/Thread.cpp +++ b/Source/core/Thread.cpp @@ -132,14 +132,14 @@ namespace Core { #endif } - ::ThreadId Thread::ThreadId() + thread_id Thread::ThreadId() { #ifdef __WINDOWS__ PUSH_WARNING(DISABLE_WARNING_CONVERSION_TO_GREATERSIZE) return (::GetCurrentThreadId()); POP_WARNING() #else - return static_cast<::ThreadId>(pthread_self()); + return static_cast(pthread_self()); #endif } diff --git a/Source/core/Thread.h b/Source/core/Thread.h index d9f71a00b..f1055352d 100644 --- a/Source/core/Thread.h +++ b/Source/core/Thread.h @@ -218,11 +218,11 @@ namespace Core { int PriorityMin() const; int PriorityMax() const; bool Priority(int priority); - inline ::ThreadId Id() const + inline thread_id Id() const { return (m_ThreadId); } - static ::ThreadId ThreadId(); + static thread_id ThreadId(); template static STORAGETYPE& GetContext() @@ -288,7 +288,7 @@ namespace Core { HANDLE m_hThreadInstance; #endif - ::ThreadId m_ThreadId; + thread_id m_ThreadId; static uint32_t _defaultStackSize; #ifdef __POSIX__ string m_threadName; diff --git a/Source/core/ThreadPool.h b/Source/core/ThreadPool.h index 461122090..ae269908b 100644 --- a/Source/core/ThreadPool.h +++ b/Source/core/ThreadPool.h @@ -51,14 +51,14 @@ namespace Core { virtual void Dispatch(IDispatch*) = 0; }; struct EXTERNAL Metadata { - ::ThreadId WorkerId; + thread_id WorkerId; uint32_t Runs; Core::OptionalType Job; }; #ifdef __CORE_WARNING_REPORTING__ struct EXTERNAL DispatchedJobMetaData { - ::ThreadId WorkerId; + thread_id WorkerId; string CallSign; uint64_t DispatchedTime; uint32_t ReportRunCount; @@ -597,7 +597,7 @@ POP_WARNING() _queue.Unlock(); } - ::ThreadId Id(const uint8_t index) const + thread_id Id(const uint8_t index) const { uint8_t count = 0; std::list::const_iterator ptr = _units.cbegin(); diff --git a/Source/core/Timer.h b/Source/core/Timer.h index 466df1eb8..e496ef5d7 100644 --- a/Source/core/Timer.h +++ b/Source/core/Timer.h @@ -329,7 +329,7 @@ namespace Core { return (static_cast(_pendingQueue.size())); } - ::ThreadId ThreadId() const + thread_id ThreadId() const { return (_timerThread.Id()); } diff --git a/Source/core/WorkerPool.h b/Source/core/WorkerPool.h index c359bbdff..28d9cc0e9 100644 --- a/Source/core/WorkerPool.h +++ b/Source/core/WorkerPool.h @@ -102,7 +102,7 @@ namespace Core { static IWorkerPool& Instance(); static bool IsAvailable(); - virtual ::ThreadId Id(const uint8_t index) const = 0; + virtual thread_id Id(const uint8_t index) const = 0; virtual void Submit(const Core::ProxyType& job) = 0; virtual void Schedule(const Core::Time& time, const Core::ProxyType& job) = 0; virtual bool Reschedule(const Core::Time& time, const Core::ProxyType& job) = 0; @@ -384,9 +384,9 @@ POP_WARNING() _external.Process(); _joined = 0; } - ::ThreadId Id(const uint8_t index) const override + thread_id Id(const uint8_t index) const override { - ::ThreadId result = (::ThreadId)(~0); + thread_id result = (thread_id)(~0); if (index == 0) { result = _timer.ThreadId(); @@ -431,7 +431,7 @@ POP_WARNING() ThreadPool::Minion _external; Core::TimerType _timer; mutable Metadata _metadata; - ::ThreadId _joined; + thread_id _joined; #ifdef __CORE_WARNING_REPORTING__ DispatchedJobMonitor _dispatchedJobMonitor; #endif diff --git a/Source/plugins/Metadata.cpp b/Source/plugins/Metadata.cpp index cee862995..eeae04ba2 100644 --- a/Source/plugins/Metadata.cpp +++ b/Source/plugins/Metadata.cpp @@ -215,7 +215,7 @@ namespace PluginHost Metadata::Server::Minion::Minion() : Core::JSON::Container() - , Id(0) + , Id() , Job() , Runs(0) { Add(_T("id"), &Id); @@ -241,7 +241,7 @@ namespace PluginHost Add(_T("runs"), &Runs); } Metadata::Server::Minion& Metadata::Server::Minion::operator=(const Core::ThreadPool::Metadata& info) { - Id = (Core::instance_id)info.WorkerId; + Id = Metadata::InstanceId(info.WorkerId); Runs = info.Runs; if (info.Job.IsSet() == false) { diff --git a/Source/plugins/Metadata.h b/Source/plugins/Metadata.h index e60c0eef4..6079ad040 100644 --- a/Source/plugins/Metadata.h +++ b/Source/plugins/Metadata.h @@ -140,8 +140,8 @@ namespace PluginHost { public: Core::JSON::InstanceId Id; - Core::JSON::String Job; - Core::JSON::DecUInt32 Runs; + Core::JSON::String Job; + Core::JSON::DecUInt32 Runs; }; public: @@ -255,6 +255,32 @@ namespace PluginHost { AppVersion.Clear(); } + template + static typename std::enable_if<(std::is_same::value), Core::instance_id>::type + InstanceId(TYPE id) + { + return reinterpret_cast(reinterpret_cast(id)); + } + template + static typename std::enable_if::value), Core::instance_id>::type + InstanceId(TYPE id) + { + return static_cast(id); + } + + template + static typename std::enable_if<(std::is_same::value), Core::thread_id>::type + ThreadId(Core::instance_id id) + { + return reinterpret_cast(id); + } + template + static typename std::enable_if::value), Core::thread_id>::type + ThreadId(Core::instance_id id) + { + return static_cast(id); + } + public: SubSystem SubSystems; Core::JSON::ArrayType Plugins; diff --git a/Tests/unit/core/test_thread.cpp b/Tests/unit/core/test_thread.cpp index 02fc96f32..03720cb53 100644 --- a/Tests/unit/core/test_thread.cpp +++ b/Tests/unit/core/test_thread.cpp @@ -38,7 +38,7 @@ namespace Core { ThreadClass(const ThreadClass&) = delete; ThreadClass& operator=(const ThreadClass&) = delete; - ThreadClass(volatile bool& threadDone, std::mutex& mutex, std::condition_variable& cv, ::ThreadId parentTid) + ThreadClass(volatile bool& threadDone, std::mutex& mutex, std::condition_variable& cv, ::Thunder::Core::thread_id parentTid) : ::Thunder::Core::Thread(::Thunder::Core::Thread::DefaultStackSize(), _T("Test")) , _done(threadDone) , _threadMutex(mutex) @@ -66,7 +66,7 @@ namespace Core { volatile bool& _done; std::mutex& _threadMutex; std::condition_variable& _threadCV; - ::ThreadId _parentTid; + ::Thunder::Core::thread_id _parentTid; }; class Job : public ::Thunder::Core::IDispatch { @@ -97,7 +97,7 @@ namespace Core { private: static bool _threadDone; - static ::ThreadId _parentTPid; + static ::Thunder::Core::thread_id _parentTPid; public: static std::mutex _mutex; @@ -107,11 +107,11 @@ namespace Core { bool Job::_threadDone = false; std::mutex Job::_mutex; std::condition_variable Job::_cv; - ::ThreadId Job::_parentTPid = ::Thunder::Core::Thread::ThreadId(); + ::Thunder::Core::thread_id Job::_parentTPid = ::Thunder::Core::Thread::ThreadId(); TEST(Core_Thread, DISABLED_SimpleThread) { - ::ThreadId parentTid = ::Thunder::Core::Thread::ThreadId(); + ::Thunder::Core::thread_id parentTid = ::Thunder::Core::Thread::ThreadId(); volatile bool threadDone = false; std::mutex mutex; std::condition_variable cv; diff --git a/Tests/unit/core/test_workerpool.cpp b/Tests/unit/core/test_workerpool.cpp index deec4df9b..b5e531e4c 100644 --- a/Tests/unit/core/test_workerpool.cpp +++ b/Tests/unit/core/test_workerpool.cpp @@ -260,10 +260,10 @@ namespace Core { const uint8_t MaxSize = 15; bool isPoolId = false; char id[MaxSize]; - sprintf(id, "%x", static_cast<::ThreadId>(pthread_self())); + sprintf(id, "%x", static_cast<::Thunder::Core::thread_id>(pthread_self())); for (uint8_t index = 0; index < _threadsCount + 2; index++) { char workerId[MaxSize]; - sprintf(workerId, "%x", static_cast<::ThreadId>(::Thunder::Core::IWorkerPool::Instance().Id(index))); + sprintf(workerId, "%x", static_cast<::Thunder::Core::thread_id>(::Thunder::Core::IWorkerPool::Instance().Id(index))); if (strcpy(workerId, id)) { isPoolId = true; From ea4a37bb327c48ff62fe864e6e7b47e11e10bef7 Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Wed, 9 Oct 2024 15:11:15 +0200 Subject: [PATCH 2/4] Update Portability.h (#1772) Probably a merge issue as the old code came back again. Always make sure thet the Preprocessor are ate the beginning of a function declaration! --- Source/core/Portability.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/core/Portability.h b/Source/core/Portability.h index 3969ddb11..395b252af 100644 --- a/Source/core/Portability.h +++ b/Source/core/Portability.h @@ -990,8 +990,8 @@ EXTERNAL extern int inet_aton(const char* cp, struct in_addr* inp); EXTERNAL extern void usleep(const uint32_t value); #endif -void EXTERNAL DumpCallStack(const Thunder::Core::thread_id threadId, std::list& stack); -uint32_t EXTERNAL GetCallStack(const Thunder::Core::thread_id threadId, void* addresses[], const uint32_t bufferSize); +EXTERNAL void DumpCallStack(const Thunder::Core::thread_id threadId, std::list& stack); +EXTERNAL uint32_t GetCallStack(const Thunder::Core::thread_id threadId, void* addresses[], const uint32_t bufferSize); } From 0161d8edb23ffadac5f49b5eee4ff1a421605916 Mon Sep 17 00:00:00 2001 From: nxtum <94901881+nxtum@users.noreply.github.com> Date: Thu, 10 Oct 2024 07:59:41 +0200 Subject: [PATCH 3/4] Replace SharedBuffer::Semaphore with Core::SharedSemaphore (#1737) * core::binarysemaphore in sharedbuffer * spelling, binairy to binary in sharedbuffer * musl fix, added sem_timedwait * fix by initializing sem * fixed logic of jump * hide sem_t * detect musl * fix windows * sem open support, max method * add unused * errors semopen * create/open sem * sharedbuffer offset calculations * add sizeof to handle * fix alignment for buffer * align buffer 32/64 * align adminstration * add variable unused * change isLocked to Count * create windowsapi for ntquerysemaphore * spelling mistake * name fix * remarks --------- Co-authored-by: Pierre Wielders --- Source/core/Portability.h | 30 ++++ Source/core/Proxy.h | 4 +- Source/core/SharedBuffer.cpp | 150 +++----------------- Source/core/SharedBuffer.h | 40 +----- Source/core/Sync.cpp | 259 +++++++++++++++++++++++++++++++++-- Source/core/Sync.h | 60 ++++++-- Source/core/Thread.cpp | 2 +- 7 files changed, 354 insertions(+), 191 deletions(-) diff --git a/Source/core/Portability.h b/Source/core/Portability.h index 395b252af..b5b44cb90 100644 --- a/Source/core/Portability.h +++ b/Source/core/Portability.h @@ -359,6 +359,20 @@ typedef std::string string; //const std::basic_string::size_type std::basic_string::npos = (std::basic_string::size_type) - 1; //#endif +// NTQuerySemaphore (undocumented) is used to retrieve current count of a semaphore +using NTSTATUS = LONG; +using _NTQuerySemaphore = NTSTATUS(NTAPI*)( + HANDLE SemaphoreHandle, + DWORD SemaphoreInformationClass, + PVOID SemaphoreInformation, + ULONG SemaphoreInformationLength, + PULONG ReturnLength OPTIONAL +); +struct SEMAPHORE_BASIC_INFORMATION { + ULONG CurrentCount; + ULONG MaximumCount; +}; + #define LITTLE_ENDIAN_PLATFORM 1 #undef ERROR #define __WINDOWS__ @@ -385,6 +399,7 @@ typedef std::string string; #include #include #include +#include #include #include @@ -412,9 +427,24 @@ typedef std::string string; #include #include #include // memfd_create in Messaging/ConsoleRedirect.h +#include #include +#ifndef _GNU_SOURCE + #define _GNU_SOURCE + #include + #ifndef __USE_GNU + #define __MUSL__ + #endif + #undef _GNU_SOURCE /* don't contaminate other includes unnecessarily */ +#else + #include + #ifndef __USE_GNU + #define __MUSL__ + #endif +#endif + #ifdef __APPLE__ #include #define SCHED_BATCH 99 diff --git a/Source/core/Proxy.h b/Source/core/Proxy.h index d51cce599..0b2830fe5 100644 --- a/Source/core/Proxy.h +++ b/Source/core/Proxy.h @@ -539,11 +539,11 @@ POP_WARNING() { return (!operator==(a_RHS)); } - inline bool operator==(const nullptr_t&) const + inline bool operator==(const std::nullptr_t&) const { return (_refCount == nullptr); } - inline bool operator!=(const nullptr_t&) const + inline bool operator!=(const std::nullptr_t&) const { return (_refCount != nullptr); } diff --git a/Source/core/SharedBuffer.cpp b/Source/core/SharedBuffer.cpp index c26704943..572b1f7d9 100644 --- a/Source/core/SharedBuffer.cpp +++ b/Source/core/SharedBuffer.cpp @@ -26,148 +26,38 @@ namespace Thunder { namespace Core { -#ifdef __WINDOWS__ - SharedBuffer::Semaphore::Semaphore(const TCHAR sourceName[]) - : _semaphore(::CreateSemaphore(nullptr, 1, 1, sourceName)) - { - } -#else - SharedBuffer::Semaphore::Semaphore(sem_t* storage) - : _semaphore(storage) - { - ASSERT(storage != nullptr); - } -#endif - SharedBuffer::Semaphore::~Semaphore() - { -#ifdef __WINDOWS__ - if (_semaphore != nullptr) { - ::CloseHandle(_semaphore); - } -#else - sem_destroy(_semaphore); -#endif - } - - uint32_t SharedBuffer::Semaphore::Unlock() - { -#ifdef __WINDOWS__ - if (_semaphore != nullptr) { - BOOL result = ::ReleaseSemaphore(_semaphore, 1, nullptr); - - ASSERT(result != FALSE); - } -#else - VARIABLE_IS_NOT_USED int result = sem_post(_semaphore); - - ASSERT((result == 0) || (errno == EOVERFLOW)); -#endif - return ERROR_NONE; - } - - bool SharedBuffer::Semaphore::IsLocked() - { -#ifdef __WINDOWS__ - bool locked = (::WaitForSingleObjectEx(_semaphore, 0, FALSE) != WAIT_OBJECT_0); - - if (locked == false) { - ::ReleaseSemaphore(_semaphore, 1, nullptr); - } - - return (locked); -#else - int semValue = 0; - sem_getvalue(_semaphore, &semValue); - return (semValue == 0); -#endif - } - - uint32_t SharedBuffer::Semaphore::Lock(const uint32_t waitTime) - { - uint32_t result = Core::ERROR_GENERAL; -#ifdef __WINDOWS__ - if (_semaphore != nullptr) { - return (::WaitForSingleObjectEx(_semaphore, waitTime, FALSE) == WAIT_OBJECT_0 ? Core::ERROR_NONE : Core::ERROR_TIMEDOUT); - } -#elif defined(__APPLE__) - - uint32_t timeLeft = waitTime; - int semResult; - while (((semResult = sem_trywait(_semaphore)) != 0) && timeLeft > 0) { - ::SleepMs(100); - if (timeLeft != Core::infinite) { - timeLeft -= (timeLeft > 100 ? 100 : timeLeft); - } - } - result = semResult == 0 ? Core::ERROR_NONE : Core::ERROR_TIMEDOUT; -#else - - struct timespec structTime = {0,0}; - - clock_gettime(CLOCK_MONOTONIC, &structTime); - structTime.tv_nsec += ((waitTime % 1000) * 1000 * 1000); /* remainder, milliseconds to nanoseconds */ - structTime.tv_sec += (waitTime / 1000) + (structTime.tv_nsec / 1000000000); /* milliseconds to seconds */ - structTime.tv_nsec = structTime.tv_nsec % 1000000000; - - do { - if (sem_clockwait(_semaphore, CLOCK_MONOTONIC, &structTime) == 0) { - result = Core::ERROR_NONE; - } - else if ( errno == EINTR ) { - continue; - } - else if ( errno == ETIMEDOUT ) { - result = Core::ERROR_TIMEDOUT; - } - else { - ASSERT(false); - } - break; - } while (true); -#endif - return (result); - } - SharedBuffer::SharedBuffer(const TCHAR name[]) : DataElementFile(name, File::USER_READ | File::USER_WRITE | File::SHAREABLE, 0) , _administrationBuffer((string(name) + ".admin"), File::USER_READ | File::USER_WRITE | File::SHAREABLE, 0) , _administration(reinterpret_cast(PointerAlign(_administrationBuffer.Buffer()))) -#ifdef __WINDOWS__ + #ifdef __WINDOWS__ , _producer((string(name) + ".producer").c_str()) , _consumer((string(name) + ".consumer").c_str()) -#else - , _producer(&(_administration->_producer)) - , _consumer(&(_administration->_consumer)) -#endif - , _customerAdministration(PointerAlign(&(reinterpret_cast(_administration)[sizeof(Administration)]))) + #else + , _producer(reinterpret_cast(_administration) + sizeof(Administration)) + , _consumer(reinterpret_cast(_administration) + sizeof(Administration) + SharedSemaphore::Size()) + #endif + , _customerAdministration(PointerAlign(&(reinterpret_cast(_administration)[sizeof(Administration) + (SharedSemaphore::Size() * 2)]))) { Align(); } SharedBuffer::SharedBuffer(const TCHAR name[], const uint32_t mode, const uint32_t bufferSize, const uint16_t administratorSize) : DataElementFile(name, mode | File::SHAREABLE | File::CREATE, bufferSize) - , _administrationBuffer((string(name) + ".admin"), mode | File::SHAREABLE | File::CREATE, administratorSize + sizeof(Administration) + (2 * sizeof(void*)) + 8 /* Align buffer on 64 bits boundary */) + , _administrationBuffer((string(name) + ".admin"), mode | File::SHAREABLE | File::CREATE, sizeof(Administration) + (SharedSemaphore::Size() * 2) + administratorSize + + (sizeof(void*) * 2) + ((sizeof(Administration) + (SharedSemaphore::Size() * 2) + administratorSize) % sizeof(void*) == 0 ? + 0 : (sizeof(void*) - ((sizeof(Administration) + (SharedSemaphore::Size() * 2) + administratorSize) % sizeof(void*)))) /* Align buffer on 32/64 bits boundary */) , _administration(reinterpret_cast(PointerAlign(_administrationBuffer.Buffer()))) -#ifdef __WINDOWS__ - , _producer((string(name) + ".producer").c_str()) - , _consumer((string(name) + ".consumer").c_str()) -#else - , _producer(&(_administration->_producer)) - , _consumer(&(_administration->_consumer)) -#endif - , _customerAdministration(PointerAlign(&(reinterpret_cast(_administration)[sizeof(Administration)]))) - { - -#ifndef __WINDOWS__ - memset(_administration, 0, sizeof(Administration)); - - sem_init(&(_administration->_producer), 1, 1); /* Initial value is 1. */ - sem_init(&(_administration->_consumer), 1, 0); /* Initial value is 0. */ -#endif + #ifdef __WINDOWS__ + , _producer((string(name) + ".producer").c_str(), 1, 1) + , _consumer((string(name) + ".consumer").c_str(), 0, 1) + #else + , _producer(reinterpret_cast(_administration) + sizeof(Administration), 1, 1) + , _consumer(reinterpret_cast(_administration) + sizeof(Administration) + SharedSemaphore::Size(), 0, 1) +# endif + , _customerAdministration(PointerAlign(&(reinterpret_cast(_administration)[sizeof(Administration) + (SharedSemaphore::Size() * 2)]))) + { + _administration->_bytesWritten = 0; Align(); } - - SharedBuffer::~SharedBuffer() - { - } -} } +} \ No newline at end of file diff --git a/Source/core/SharedBuffer.h b/Source/core/SharedBuffer.h index 664e34d98..77035525d 100644 --- a/Source/core/SharedBuffer.h +++ b/Source/core/SharedBuffer.h @@ -65,46 +65,12 @@ namespace Core { SharedBuffer& operator=(const SharedBuffer&) = delete; private: - class Semaphore { - private: - Semaphore() = delete; - Semaphore(const Semaphore&) = delete; - Semaphore& operator=(const Semaphore&) = delete; - - public: -#ifdef __WINDOWS__ - Semaphore(const TCHAR name[]); -#else - Semaphore(sem_t* storage); - //Semaphore(sem_t* storage, bool initialize) { - //} -#endif - ~Semaphore(); - - public: - uint32_t Lock(const uint32_t waitTime); - uint32_t Unlock(); - bool IsLocked(); - - private: -#ifdef __WINDOWS__ - HANDLE _semaphore; -#else - sem_t* _semaphore; -#endif - }; struct Administration { - uint32_t _bytesWritten; - -#ifndef __WINDOWS__ - sem_t _producer; - sem_t _consumer; -#endif }; public: - virtual ~SharedBuffer(); + ~SharedBuffer() override = default; // This is the consumer constructor. It should always take place, after, the producer // construct. The producer will create the Administration area, and the shared buffer, @@ -215,8 +181,8 @@ namespace Core { private: DataElementFile _administrationBuffer; Administration* _administration; - Semaphore _producer; - Semaphore _consumer; + Core::SharedSemaphore _producer; + Core::SharedSemaphore _consumer; uint8_t* _customerAdministration; }; } diff --git a/Source/core/Sync.cpp b/Source/core/Sync.cpp index e5f04ef3a..545161e0d 100644 --- a/Source/core/Sync.cpp +++ b/Source/core/Sync.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #endif #ifdef __APPLE__ #include @@ -271,7 +272,7 @@ namespace Core { //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- - // BinairySemaphore class + // BinarySemaphore class //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -283,12 +284,12 @@ namespace Core { // sets the inital count an the maximum count. This way, on platform changes, // only the declaration/definition of the synchronisation object has to be defined // as being Binairy, not the coding. - BinairySemaphore::BinairySemaphore(unsigned int nInitialCount, unsigned int nMaxCount) + BinarySemaphore::BinarySemaphore(unsigned int nInitialCount, unsigned int nMaxCount) { DEBUG_VARIABLE(nMaxCount); ASSERT((nInitialCount == 0) || (nInitialCount == 1)); - TRACE_L5("Constructor BinairySemaphore (int, int) <%p>", (this)); + TRACE_L5("Constructor BinarySemaphore (int, int) <%p>", (this)); #ifdef __POSIX__ m_blLocked = (nInitialCount == 0); @@ -323,12 +324,12 @@ namespace Core { #endif } - BinairySemaphore::BinairySemaphore(bool blLocked) + BinarySemaphore::BinarySemaphore(bool blLocked) #ifdef __POSIX__ : m_blLocked(blLocked) #endif { - TRACE_L5("Constructor BinairySemaphore <%p>", (this)); + TRACE_L5("Constructor BinarySemaphore <%p>", (this)); #ifdef __POSIX__ pthread_condattr_t attr; @@ -360,9 +361,9 @@ namespace Core { #endif } - BinairySemaphore::~BinairySemaphore() + BinarySemaphore::~BinarySemaphore() { - TRACE_L5("Destructor BinairySemaphore <%p>", (this)); + TRACE_L5("Destructor BinarySemaphore <%p>", (this)); #ifdef __POSIX__ // If we really create it, we really have to destroy it. @@ -380,7 +381,7 @@ namespace Core { //---------------------------------------------------------------------------- uint32_t - BinairySemaphore::Lock() + BinarySemaphore::Lock() { #ifdef __WINDOWS__ @@ -423,7 +424,7 @@ namespace Core { } uint32_t - BinairySemaphore::Lock(unsigned int nTime) + BinarySemaphore::Lock(unsigned int nTime) { #ifdef __WINDOWS__ return (::WaitForSingleObjectEx(m_syncMutex, nTime, FALSE) == WAIT_OBJECT_0 ? Core::ERROR_NONE : Core::ERROR_TIMEDOUT); @@ -482,8 +483,8 @@ namespace Core { #endif } - void - BinairySemaphore::Unlock() + uint32_t + BinarySemaphore::Unlock() { #ifdef __POSIX__ @@ -505,6 +506,7 @@ namespace Core { #ifdef __WINDOWS__ ::ReleaseMutex(m_syncMutex); #endif + return ERROR_NONE; } //---------------------------------------------------------------------------- @@ -782,6 +784,241 @@ namespace Core { return (nResult); } + //---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- + // SharedSemaphore class + //---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- + + //---------------------------------------------------------------------------- + // CONSTRUCTOR & DESTRUCTOR + //---------------------------------------------------------------------------- + +#ifdef __WINDOWS__ + class WindowsAPI { + public: + WindowsAPI(WindowsAPI&&) = delete; + WindowsAPI(const WindowsAPI&) = delete; + WindowsAPI& operator=(WindowsAPI&&) = delete; + WindowsAPI& operator=(const WindowsAPI&) = delete; + + ~WindowsAPI() = default; + WindowsAPI() { + _ntQuerySemaphore = reinterpret_cast<_NTQuerySemaphore>(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQuerySemaphore")); + ASSERT (_ntQuerySemaphore != nullptr); + } + + uint32_t GetSemaphoreCount(HANDLE parameter) const { + SEMAPHORE_BASIC_INFORMATION basicInfo; + NTSTATUS status; + status = _ntQuerySemaphore(parameter, 0, &basicInfo, sizeof(SEMAPHORE_BASIC_INFORMATION), nullptr); + return (status == ERROR_SUCCESS) ? basicInfo.CurrentCount : 0; + } + private: + _NTQuerySemaphore _ntQuerySemaphore; + }; + + static WindowsAPI _windowsAPI; +#endif + + SharedSemaphore::SharedSemaphore(const TCHAR sourceName[], const uint32_t initCount, VARIABLE_IS_NOT_USED const uint32_t maxCount) + { + ASSERT(initCount <= 1); + ASSERT(maxCount == 1); +#ifdef __WINDOWS__ + _semaphore = (::CreateSemaphore(nullptr, initCount, maxCount, sourceName)); + ASSERT(_semaphore != nullptr); +#else + _name = "/" + string(sourceName); + _semaphore = sem_open(_name.c_str(), O_CREAT | O_RDWR | O_EXCL, 0644, initCount); + ASSERT(_semaphore != SEM_FAILED); +#endif + } + + SharedSemaphore::SharedSemaphore(const TCHAR sourceName[]) + { +#ifdef __WINDOWS__ + _semaphore = ::OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, sourceName); + ASSERT(_semaphore != nullptr); +#else + _semaphore = sem_open(sourceName, 0); + ASSERT(_semaphore != nullptr); +#endif + } + +#ifndef __WINDOWS__ + SharedSemaphore::SharedSemaphore(void* storage, const uint32_t initCount, VARIABLE_IS_NOT_USED const uint32_t maxCount) + : _semaphore(storage), _name("") + { + ASSERT(storage != nullptr); + ASSERT(initCount <= 1); + ASSERT(maxCount == 1); + memset(_semaphore, 0, sizeof(sem_t)); + VARIABLE_IS_NOT_USED int result = sem_init(static_cast(_semaphore), 1, initCount); + ASSERT(result != -1); + } + + SharedSemaphore::SharedSemaphore(void* storage) + : _semaphore(storage), _name("") + { + ASSERT(storage != nullptr); + } + +#endif + + SharedSemaphore::~SharedSemaphore() + { +#ifdef __WINDOWS__ + if (_semaphore != nullptr) { + ::CloseHandle(_semaphore); + } +#else + if(_name.size() != 0) { + sem_close(static_cast(_semaphore)); + sem_unlink(_name.c_str()); + } + else { + sem_destroy(static_cast(_semaphore)); + } +#endif + } + + size_t SharedSemaphore::Size() + { +#ifdef __WINDOWS__ + return sizeof(HANDLE); +#else + return sizeof(sem_t); +#endif + } + + uint32_t SharedSemaphore::MaxCount() const + { + // Currently max count is 1, as it is implemented as a binary shared semaphore + return 1; + } + + //---------------------------------------------------------------------------- + // PUBLIC METHODS + //---------------------------------------------------------------------------- + + uint32_t + SharedSemaphore::Unlock() + { +#ifdef __WINDOWS__ + if (_semaphore != nullptr) { + BOOL result = ::ReleaseSemaphore(_semaphore, 1, nullptr); + ASSERT(result != FALSE); + } +#else + VARIABLE_IS_NOT_USED int result = sem_post(static_cast(_semaphore)); + ASSERT((result == 0) || (errno == EOVERFLOW)); +#endif + return ERROR_NONE; + } + + uint32_t + SharedSemaphore::Count() const + { +#ifdef __WINDOWS__ + return (_windowsAPI.GetSemaphoreCount(_semaphore)); +#else + int semValue = 0; + sem_getvalue(static_cast(_semaphore), &semValue); + return semValue; +#endif + } + + uint32_t + SharedSemaphore::Lock(const uint32_t waitTime) + { + uint32_t result = Core::ERROR_GENERAL; +#ifdef __WINDOWS__ + if (_semaphore != nullptr) { + return (::WaitForSingleObjectEx(_semaphore, waitTime, FALSE) == WAIT_OBJECT_0 ? Core::ERROR_NONE : Core::ERROR_TIMEDOUT); + } +#elif defined(__APPLE__) + + uint32_t timeLeft = waitTime; + int semResult; + while (((semResult = sem_trywait(static_cast(_semaphore))) != 0) && timeLeft > 0) { + ::SleepMs(100); + if (timeLeft != Core::infinite) { + timeLeft -= (timeLeft > 100 ? 100 : timeLeft); + } + } + result = semResult == 0 ? Core::ERROR_NONE : Core::ERROR_TIMEDOUT; + +#elif defined(__MUSL__) + struct timespec referenceTime = {0,0}; + clock_gettime(CLOCK_MONOTONIC, &referenceTime); + referenceTime.tv_nsec += ((waitTime % 1000) * 1000 * 1000); /* remainder, milliseconds to nanoseconds */ + referenceTime.tv_sec += (waitTime / 1000) + (referenceTime.tv_nsec / 1000000000); /* milliseconds to seconds */ + referenceTime.tv_nsec = referenceTime.tv_nsec % 1000000000; + do { + + struct timespec structTime = {0,0}; + clock_gettime(CLOCK_REALTIME, &structTime); + structTime.tv_nsec += ((waitTime % 1000) * 1000 * 1000); /* remainder, milliseconds to nanoseconds */ + structTime.tv_sec += (waitTime / 1000) + (structTime.tv_nsec / 1000000000); /* milliseconds to seconds */ + structTime.tv_nsec = structTime.tv_nsec % 1000000000; + + if (sem_timedwait(static_cast(_semaphore), &structTime) == 0) { + result = Core::ERROR_NONE; + } + else if ( errno == EINTR ) { + continue; + } + else if ( errno == ETIMEDOUT ) { + struct timespec currentMonoTime; + clock_gettime(CLOCK_MONOTONIC, ¤tMonoTime); + + struct timespec jumpTime; + jumpTime.tv_sec = currentMonoTime.tv_sec - referenceTime.tv_sec; + + if(jumpTime.tv_sec != 0) { + result = Core::ERROR_TIMEDOUT; + break; + } + + if(referenceTime.tv_sec < currentMonoTime.tv_sec || (referenceTime.tv_sec == currentMonoTime.tv_sec && + referenceTime.tv_nsec < currentMonoTime.tv_nsec)) + { + result = Core::ERROR_TIMEDOUT; + break; + } + } + else { + ASSERT(false); + } + break; + } while (true); +#else + struct timespec structTime = {0,0}; + clock_gettime(CLOCK_MONOTONIC, &structTime); + structTime.tv_nsec += ((waitTime % 1000) * 1000 * 1000); /* remainder, milliseconds to nanoseconds */ + structTime.tv_sec += (waitTime / 1000) + (structTime.tv_nsec / 1000000000); /* milliseconds to seconds */ + structTime.tv_nsec = structTime.tv_nsec % 1000000000; + + do { + if (sem_clockwait(static_cast(_semaphore), CLOCK_MONOTONIC, &structTime) == 0) { + result = Core::ERROR_NONE; + } + else if ( errno == EINTR ) { + continue; + } + else if ( errno == ETIMEDOUT ) { + result = Core::ERROR_TIMEDOUT; + } + else { + ASSERT(false); + } + break; + } while (true); +#endif + return (result); + } + //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Event class (AVAILABLE WITHIN PROCESS SPACE) diff --git a/Source/core/Sync.h b/Source/core/Sync.h index 63540c773..fbe30a663 100644 --- a/Source/core/Sync.h +++ b/Source/core/Sync.h @@ -29,7 +29,6 @@ #ifdef __LINUX__ #include -#include #endif namespace Thunder { @@ -112,23 +111,22 @@ namespace Core { // =========================================================================== // class BinairySemaphore // =========================================================================== - - class EXTERNAL BinairySemaphore { + class EXTERNAL BinarySemaphore { private: - BinairySemaphore() = delete; - BinairySemaphore(const BinairySemaphore&) = delete; - BinairySemaphore& operator=(const BinairySemaphore&) = delete; + BinarySemaphore() = delete; + BinarySemaphore(const BinarySemaphore&) = delete; + BinarySemaphore& operator=(const BinarySemaphore&) = delete; public: // Methods - BinairySemaphore(unsigned int nInitialCount, unsigned int nMaxCount); - BinairySemaphore(bool blLocked); - ~BinairySemaphore(); + BinarySemaphore(unsigned int nInitialCount, unsigned int nMaxCount); + BinarySemaphore(bool blLocked); + ~BinarySemaphore(); uint32_t Lock(); // Time in milliseconds! uint32_t Lock(unsigned int nSeconds); - void Unlock(); + uint32_t Unlock(); bool Locked() const; protected: // Members @@ -143,6 +141,9 @@ namespace Core { #endif }; + // For compatability reaons with old class name + using BinairySemaphore = BinarySemaphore; + // =========================================================================== // class CountingSemaphore // =========================================================================== @@ -181,6 +182,45 @@ namespace Core { // For Windows platform compatibility typedef CountingSemaphore Semaphore; + // =========================================================================== + // class SharedSemaphore + // =========================================================================== + + class EXTERNAL SharedSemaphore { + public: + SharedSemaphore() = delete; + SharedSemaphore(const Semaphore&) = delete; + SharedSemaphore& operator=(const SharedSemaphore&) = delete; + + SharedSemaphore(const TCHAR name[], const uint32_t initValue, const uint32_t maxValue); + SharedSemaphore(const TCHAR name[]); +#ifndef __WINDOWS__ + /* + If pshared is nonzero, then the semaphore is shared between + processes, and should be located in a region of shared memory + (see shm_open(3), mmap(2), and shmget(2)) + Storage should be at least sizeof(sem_t)! + */ + SharedSemaphore(void *storage, const uint32_t initValue, const uint32_t maxValue); + SharedSemaphore(void *storage); + public: +#endif + ~SharedSemaphore(); + public: + uint32_t Lock(const uint32_t waitTime); + uint32_t Unlock(); + uint32_t Count() const; + static size_t Size(); + uint32_t MaxCount() const; + private: +#ifdef __WINDOWS__ + HANDLE _semaphore; +#else + void* _semaphore; + string _name; +#endif + }; + // =========================================================================== // class Event // =========================================================================== diff --git a/Source/core/Thread.cpp b/Source/core/Thread.cpp index b635c20f4..b5251b310 100644 --- a/Source/core/Thread.cpp +++ b/Source/core/Thread.cpp @@ -469,7 +469,7 @@ POP_WARNING() } #ifdef __DEBUG__ - int Thread::GetCallstack(void** buffer, int size) + int Thread::GetCallstack(VARIABLE_IS_NOT_USED void** buffer, VARIABLE_IS_NOT_USED int size) { #if defined(THUNDER_BACKTRACE) return GetCallStack(m_hThreadInstance, buffer, size); From 456ee8db806f510e03946403b607a0934c433e99 Mon Sep 17 00:00:00 2001 From: Mateusz Daniluk <121170681+VeithMetro@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:29:58 +0200 Subject: [PATCH 4/4] [Actions] Fix errors due to an update of GitHub hosted runners (#1774) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Try to install jsonref with pipx in the external env * Use the development template to test the patch * Cannot use pipx on this runner, try to create a virtual env instead * Make sure to activate the virtual enviroment before building * Move the activation after the paths update * Try with sudo * Make sure to only activate the venv when needed * Remove the advanced download as it might casue issues * Make the installation easier * Try pipx in a different wa * Try without sudo * Try venv again * Use pip instead of pipx * Remove installing of jsonref for now to test * Remove venv activation for now * For now install everything apart from jsonref to isolate the issue * Remove deactivation of venv * Add venv again but don't active it yet in the generators * See if activating the venv fixes this single issue with c++ compiler * Activate the venv for the Thunder build as well * Add the libstdc++-multilib to the 32-bit build It looks like the 32-bit C++ compiler is missing... * Install libstdc++-11-dev:i386 instead * Add libc6-dev:i386 * Look for Alternative Package Names * Make sure to install GCC 13 multilib instead of 11 * Add using CHANNEL::Handle * Handle in SocketPort is private so cannot use using * Disable the overloaded virtuals warning * Move the warning push from cpp to the header * Add a PUSH_WARNING(DISABLE_WARNING_OVERLOADED_VIRTUALS) to Handle() * Fix the free() call on a pointer with the nonzero offset FAILED: Source/com/CMakeFiles/ThunderCOM.dir/Communicator.cpp.o /usr/bin/c++ -DBLUEZ_HAS_NO_INCLUSIVE_LANGUAGE -DCOM_EXPORTS -DNO_INCLUSIVE_LANGUAGE -DPROCESSCONTAINERS_ENABLED=1 -DThunderCOM_EXPORTS -DWARNING_REPORTING_ENABLED -D_TRACE_LEVEL=0 -D__CORE_BLUETOOTH_SUPPORT__ -D__CORE_MESSAGING__ -D__CORE_NO_WCHAR_SUPPORT__ -D__CORE_WARNING_REPORTING__ -I/home/runner/work/Thunder/Thunder/Release/build/Thunder/Source/com -I/home/runner/work/Thunder/Thunder/Thunder/Source/com -I/home/runner/work/Thunder/Thunder/Release/build/Thunder/Source/core -I/home/runner/work/Thunder/Thunder/Release/build/Thunder/Source/core/core -I/home/runner/work/Thunder/Thunder/Release/build/Thunder/Source/core/generated/core -I/home/runner/work/Thunder/Thunder/Thunder/Source/core/.. -I/home/runner/work/Thunder/Thunder/Thunder/Source/messaging -I/home/runner/work/Thunder/Thunder/Thunder/Source/messaging/.. -I/home/runner/work/Thunder/Thunder/Thunder/Source/extensions/warningreporting -I/home/runner/work/Thunder/Thunder/Thunder/Source/extensions/warningreporting/.. -I/home/runner/work/Thunder/Thunder/Thunder/Source/extensions/processcontainers -I/home/runner/work/Thunder/Thunder/Thunder/Source/extensions/processcontainers/.. -Wall -Wextra -Wpedantic -Werror -m64 -O3 -DNDEBUG -std=gnu++11 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -Wno-psabi -MD -MT Source/com/CMakeFiles/ThunderCOM.dir/Communicator.cpp.o -MF Source/com/CMakeFiles/ThunderCOM.dir/Communicator.cpp.o.d -o Source/com/CMakeFiles/ThunderCOM.dir/Communicator.cpp.o -c /home/runner/work/Thunder/Thunder/Thunder/Source/com/Communicator.cpp In file included from /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/Singleton.h:30, from /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/ResourceMonitor.h:24, from /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/DoorBell.h:23, from /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/core.h:35, from /home/runner/work/Thunder/Thunder/Thunder/Source/com/Module.h:26, from /home/runner/work/Thunder/Thunder/Thunder/Source/com/Communicator.h:24, from /home/runner/work/Thunder/Thunder/Thunder/Source/com/Communicator.cpp:20: In static member function ‘static void Thunder::Core::ProxyObject::operator delete(void*) [with CONTEXT = Thunder::Core::IPCMessageType<1, Thunder::RPC::Data::Init, Thunder::RPC::Data::Setup>]’, inlined from ‘Thunder::Core::ProxyObject::~ProxyObject() [with CONTEXT = Thunder::Core::IPCMessageType<1, Thunder::RPC::Data::Init, Thunder::RPC::Data::Setup>]’ at /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/Proxy.h:119:13, inlined from ‘uint32_t Thunder::Core::ProxyObject::Release() const [with CONTEXT = Thunder::Core::IPCMessageType<1, Thunder::RPC::Data::Init, Thunder::RPC::Data::Setup>]’ at /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/Proxy.h:138:21, inlined from ‘Thunder::Core::ProxyType::~ProxyType() [with CONTEXT = Thunder::Core::IPCMessageType<1, Thunder::RPC::Data::Init, Thunder::RPC::Data::Setup>]’ at /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/Proxy.h:439:39, inlined from ‘virtual void Thunder::RPC::CommunicatorClient::StateChange()’ at /home/runner/work/Thunder/Thunder/Thunder/Source/com/Communicator.cpp:524:66: /home/runner/work/Thunder/Thunder/Thunder/Source/core/../core/Proxy.h:97:23: error: ‘void free(void*)’ called on pointer ‘’ with nonzero offset 1056 [-Werror=free-nonheap-object] 97 | ::free(stAllocateBlock); | ~~~~~~^~~~~~~~~~~~~~~~~ cc1plus: all warnings being treated as errors * Don't forget to free the originalPointer * Add using Core::WorkerPool::Snapshot to the WorkerPoolImpl * Remove the changes as they don't fix the issue * Try one more solution * Try one more idea.. * Add DISABLE_WARNING_FREE_NONHEAP_OBJECT * Suppress the warning for now and investigate futher later on * Developnment finished, use the master template again * Install jsonref in venv for the tests as well * Sadly we have to do the merging twice --- .github/workflows/Build Thunder on Linux.yml | 2 +- .github/workflows/Linux build template.yml | 8 ++++++-- .github/workflows/Test Thunder.yml | 7 +++++-- Source/Thunder/PluginServer.h | 2 ++ Source/core/Portability.h | 2 ++ Source/core/Proxy.h | 2 ++ Source/core/SocketPort.h | 2 ++ 7 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Build Thunder on Linux.yml b/.github/workflows/Build Thunder on Linux.yml index 1cbe4b686..6255548b4 100644 --- a/.github/workflows/Build Thunder on Linux.yml +++ b/.github/workflows/Build Thunder on Linux.yml @@ -17,7 +17,7 @@ on: jobs: Thunder: - uses: rdkcentral/Thunder/.github/workflows/Linux build template.yml@master + uses: rdkcentral/Thunder/.github/workflows/Linux build template.yml@development/actions-pep668-error # change back to master after Actions work again ThunderInterfaces: needs: Thunder diff --git a/.github/workflows/Linux build template.yml b/.github/workflows/Linux build template.yml index 81f52d83d..99f918538 100644 --- a/.github/workflows/Linux build template.yml +++ b/.github/workflows/Linux build template.yml @@ -28,8 +28,10 @@ jobs: echo "deb http://archive.ubuntu.com/ubuntu/ jammy-updates main universe restricted multiverse" | sudo tee -a /etc/apt/sources.list ${{matrix.architecture == '32' && 'sudo dpkg --add-architecture i386' || ':'}} sudo apt-get update - sudo apt install python3-pip build-essential cmake ninja-build libusb-1.0-0-dev ${{matrix.architecture == '32' && 'zlib1g-dev:i386 libssl-dev:i386 libsbc-dev:i386 gcc-11-multilib g++-11-multilib' || 'zlib1g-dev libssl-dev libsbc-dev'}} - sudo pip install jsonref + sudo apt install python3-pip build-essential cmake ninja-build libusb-1.0-0-dev ${{matrix.architecture == '32' && 'zlib1g-dev:i386 libssl-dev:i386 libsbc-dev:i386 gcc-13-multilib g++-13-multilib' || 'zlib1g-dev libssl-dev libsbc-dev'}} + python3 -m venv venv + source venv/bin/activate + pip install jsonref # ----- Checkout & DependsOn regex ----- # --------- Thunder ---------- @@ -85,6 +87,7 @@ jobs: # ----- Installing generators & Options regex ----- - name: Install generators run: | + source venv/bin/activate ${{matrix.architecture == '32' && 'export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig:$PKG_CONFIG_PATH' || 'PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH'}} cmake -G Ninja -S ThunderTools -B ${{matrix.build_type}}/build/ThunderTools \ -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic -Werror -m${{matrix.architecture}}" \ @@ -104,6 +107,7 @@ jobs: # ----- Building & uploading artifacts ----- - name: Build Thunder run: | + source venv/bin/activate ${{matrix.architecture == '32' && 'export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig:$PKG_CONFIG_PATH' || 'PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH'}} cmake -G Ninja -S Thunder -B ${{matrix.build_type}}/build/Thunder \ -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic -Werror -m${{matrix.architecture}}" \ diff --git a/.github/workflows/Test Thunder.yml b/.github/workflows/Test Thunder.yml index 1e831f9df..6c589cdbf 100644 --- a/.github/workflows/Test Thunder.yml +++ b/.github/workflows/Test Thunder.yml @@ -40,9 +40,10 @@ jobs: sudo gem install apt-spy2 sudo apt-spy2 fix --commit --launchpad --country=US sudo apt-get update - sudo apt install python3-pip + sudo apt install python3-pip build-essential cmake ninja-build libusb-1.0-0-dev zlib1g-dev libssl-dev libgtest-dev + python3 -m venv venv + source venv/bin/activate pip install jsonref - sudo apt install build-essential cmake ninja-build libusb-1.0-0-dev zlib1g-dev libssl-dev libgtest-dev # ----- Checkout & DependsOn Regex ----- # -------------- Thunder --------------- @@ -98,12 +99,14 @@ jobs: # ----- Building ----- - name: Install generators run: | + source venv/bin/activate cmake -G Ninja -S ThunderTools -B ${{matrix.build_type}}/build/ThunderTools \ -DCMAKE_INSTALL_PREFIX=${{matrix.build_type}}/install/usr cmake --build ${{matrix.build_type}}/build/ThunderTools --target install - name: Build Thunder run: | + source venv/bin/activate cmake -G Ninja -S Thunder -B ${{matrix.build_type}}/build/Thunder \ -DBINDING="127.0.0.1" \ -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index 5614b66b9..149085ea4 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -148,6 +148,8 @@ namespace PluginHost { }; public: + using Core::WorkerPool::Snapshot; + WorkerPoolImplementation() = delete; WorkerPoolImplementation(WorkerPoolImplementation&&) = delete; WorkerPoolImplementation(const WorkerPoolImplementation&) = delete; diff --git a/Source/core/Portability.h b/Source/core/Portability.h index b5b44cb90..cd419b3a4 100644 --- a/Source/core/Portability.h +++ b/Source/core/Portability.h @@ -190,6 +190,7 @@ #define DISABLE_WARNING_DELETE_INCOMPLETE #define DISABLE_WARNING_INCONSISTENT_MISSING_OVERRIDE #define DISABLE_WARNING_MAYBE_UNINITIALIZED +#define DISABLE_WARNING_FREE_NONHEAP_OBJECT #else #define DISABLE_WARNING_CONDITIONAL_EXPRESSION_IS_CONSTANT @@ -221,6 +222,7 @@ #define DISABLE_WARNING_DELETE_INCOMPLETE PUSH_WARNING_ARG_("-Wdelete-incomplete") #define DISABLE_WARNING_INCONSISTENT_MISSING_OVERRIDE PUSH_WARNING_ARG_("-Winconsistent-missing-override") #define DISABLE_WARNING_MAYBE_UNINITIALIZED PUSH_WARNING_ARG_("-Wmaybe-uninitialized") +#define DISABLE_WARNING_FREE_NONHEAP_OBJECT PUSH_WARNING_ARG_("-Wfree-nonheap-object") #endif #endif diff --git a/Source/core/Proxy.h b/Source/core/Proxy.h index 0b2830fe5..431cb4271 100644 --- a/Source/core/Proxy.h +++ b/Source/core/Proxy.h @@ -94,7 +94,9 @@ namespace Thunder { void* stAllocateBlock) { reinterpret_cast*>(stAllocateBlock)->__Destructed(); +PUSH_WARNING(DISABLE_WARNING_FREE_NONHEAP_OBJECT) ::free(stAllocateBlock); +POP_WARNING() } public: diff --git a/Source/core/SocketPort.h b/Source/core/SocketPort.h index d026b15bc..efadf89bb 100644 --- a/Source/core/SocketPort.h +++ b/Source/core/SocketPort.h @@ -276,7 +276,9 @@ namespace Thunder { return (((m_SocketType == LISTEN) || (m_SocketType == STREAM)) ? SOCK_STREAM : ((m_SocketType == DATAGRAM) ? SOCK_DGRAM : (m_SocketType == SEQUENCED ? SOCK_SEQPACKET : SOCK_RAW))); } uint16_t Events() override; +PUSH_WARNING(DISABLE_WARNING_OVERLOADED_VIRTUALS) void Handle(const uint16_t events) override; +POP_WARNING() bool Closed(); void Opened(); void Accepted();