From caf8bfdac1067d92b159fcb1c9554f36c85b0183 Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Tue, 2 Jul 2024 09:04:54 +0200 Subject: [PATCH 1/6] [OOP] Move the plugin as a whole OOP. (#1679) --- Source/plugins/IShell.h | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Source/plugins/IShell.h b/Source/plugins/IShell.h index d0411d746..de0e09f9a 100644 --- a/Source/plugins/IShell.h +++ b/Source/plugins/IShell.h @@ -1,5 +1,5 @@ /* - * If not stated otherwise in this file or this component's LICENSE file the + * If not stated otherwise in this file or this component's LICENSE file the * following copyright and licenses apply: * * Copyright 2020 Metrological @@ -280,33 +280,42 @@ namespace PluginHost { /* @stubgen:stub */ virtual uint32_t Submit(const uint32_t Id, const Core::ProxyType& response) = 0; - inline void Register(RPC::IRemoteConnection::INotification* sink) + inline Core::hresult Register(RPC::IRemoteConnection::INotification* sink) { + Core::hresult result; + ASSERT(sink != nullptr); ICOMLink* handler(QueryInterface()); - // This method can only be used in the main process. Only this process, can instantiate a new process - ASSERT(handler != nullptr); - - if (handler != nullptr) { + if (handler == nullptr) { + result = Core::ERROR_NOT_SUPPORTED; + } + else { handler->Register(sink); handler->Release(); + result = Core::ERROR_NONE; } + + return (result); } - inline void Unregister(const RPC::IRemoteConnection::INotification* sink) + inline Core::hresult Unregister(const RPC::IRemoteConnection::INotification* sink) { + Core::hresult result; + ASSERT(sink != nullptr); ICOMLink* handler(QueryInterface()); - // This method can only be used in the main process. Only this process, can instantiate a new process - ASSERT(handler != nullptr); - - if (handler != nullptr) { + if (handler == nullptr) { + result = Core::ERROR_NOT_SUPPORTED; + } + else { handler->Unregister(sink); handler->Release(); } + + return (result); } inline void Register(ICOMLink::INotification* sink) { @@ -365,9 +374,6 @@ namespace PluginHost { RPC::IRemoteConnection* connection(nullptr); ICOMLink* handler(QueryInterface()); - // This method can only be used in the main process. Only this process, can instantiate a new process - ASSERT(handler != nullptr); - if (handler != nullptr) { connection = handler->RemoteConnection(connectionId); handler->Release(); From 850b57b9c18f3857ce2d08caea283f6d1c742468 Mon Sep 17 00:00:00 2001 From: HaseenaSainul <41037131+HaseenaSainul@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:25:30 +0530 Subject: [PATCH 2/6] Bringup of Thunder on MACOS (#1680) Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> --- .gitignore | 13 +- CMakeLists.txt | 6 +- Source/CMakeLists.txt | 10 +- Source/Thunder/PluginHost.cpp | 4 + Source/Thunder/PluginServer.cpp | 2 +- Source/Thunder/PluginServer.h | 13 +- Source/Thunder/SystemInfo.h | 6 +- Source/ThunderPlugin/Process.cpp | 3 +- Source/com/Administrator.cpp | 4 +- Source/com/Administrator.h | 2 + Source/com/Communicator.h | 3 +- Source/com/IUnknown.h | 11 +- Source/com/IteratorType.h | 2 + Source/com/Messages.h | 2 +- Source/core/ASN1.h | 4 + Source/core/CMakeLists.txt | 4 + Source/core/DataElement.h | 2 + Source/core/DataElementFile.h | 2 +- Source/core/DoorBell.cpp | 15 +- Source/core/FileObserver.h | 79 ++++++++- Source/core/IPCConnector.h | 6 +- Source/core/JSON.h | 6 +- Source/core/JSONRPC.h | 4 +- Source/core/MessageStore.cpp | 3 +- Source/core/Netlink.cpp | 2 + Source/core/Netlink.h | 2 +- Source/core/NetworkInfo.cpp | 206 ++++++++++++++++++++++-- Source/core/NetworkInfo.h | 6 +- Source/core/NodeId.h | 14 +- Source/core/Number.h | 3 +- Source/core/Portability.h | 7 + Source/core/Process.h | 8 +- Source/core/ProcessInfo.cpp | 18 ++- Source/core/Proxy.h | 2 + Source/core/ResourceMonitor.h | 64 +++++++- Source/core/SocketPort.cpp | 32 +++- Source/core/SocketPort.h | 22 +-- Source/core/Sync.cpp | 10 +- Source/core/SystemInfo.cpp | 11 +- Source/core/Thread.cpp | 39 +++-- Source/core/Thread.h | 9 ++ Source/core/Time.cpp | 31 ++-- Source/core/Trace.cpp | 3 + Source/core/Trace.h | 10 +- Source/core/WorkerPool.h | 2 +- Source/messaging/MessageClient.h | 11 +- Source/plugins/Channel.h | 4 +- Source/plugins/Metadata.h | 7 +- Source/websocket/WebLink.h | 2 +- Source/websocket/WebRequest.h | 30 ++-- Source/websocket/WebResponse.h | 8 +- Source/websocket/WebSerializer.cpp | 22 +-- Tests/redirect/main.cpp | 2 +- Tests/unit/CMakeLists.txt | 5 +- Tests/unit/IPTestAdministrator.cpp | 25 +++ Tests/unit/core/CMakeLists.txt | 16 +- Tests/unit/core/test_cyclicbuffer.cpp | 4 + Tests/unit/core/test_hash.cpp | 2 +- Tests/unit/core/test_jsonparser.cpp | 6 +- Tests/unit/core/test_library.cpp | 2 + Tests/unit/core/test_numbertype.cpp | 4 - Tests/unit/core/test_rpc.cpp | 8 +- Tests/unit/core/test_singleton.cpp | 2 + Tests/unit/core/test_systeminfo.cpp | 4 + Tests/unit/core/test_workerpool.cpp | 6 +- cmake/common/CompileSettingsDebug.cmake | 4 +- cmake/project.cmake.in | 4 +- 67 files changed, 686 insertions(+), 199 deletions(-) diff --git a/.gitignore b/.gitignore index 07447b905..6478cb576 100644 --- a/.gitignore +++ b/.gitignore @@ -46,9 +46,16 @@ workspace/ /artifacts/Release *.pyc Source/Thunder/Thunder -Source/Thunder/Thunder-1.0.0 +Source/Thunder/Thunder-* +Source/Thunder/config/ Source/ThunderPlugin/ThunderPlugin -Source/ThunderPlugin/ThunderPlugin-1.0.0 -Source/Thunder/scripts/wpeframework +Source/ThunderPlugin/ThunderPlugin-* +Source/extensions/localtracer/example/local_trace_test +Source/extensions/privilegedrequest/example/fdpassing +Source/messaging/tracing.h +Source/plugins/json/ +Thunder.cmake */*/generated/ +*/*/*/generated/ +install_manifest.txt site/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 886d31f6d..3bf521ae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,11 @@ if(APPLE) set(CMAKE_MACOSX_RPATH ON) set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") + # the RPATH to be used when installing, but only if it's not a system directory + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) + if("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + endif("${isSystemDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) endif() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index f82f638dc..50fe196d5 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -53,8 +53,8 @@ endif() if(ENABLE_STRICT_COMPILER_SETTINGS) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - message(FATAL_ERROR "Compiling with Clang") - set(CMAKE_STRICT_COMPILER_SETTINGS "-Weverything -Wextra -Wpedantic -Werror") + message(STATUS "Compiling with Clang") + set(CMAKE_STRICT_COMPILER_SETTINGS "-Wall -Wextra -Wpedantic") set(CMAKE_STRICT_CXX_COMPILER_SETTINGS "${CMAKE_STRICT_COMPILER_SETTINGS} -Wnon-virtual-dtor") elseif(${CMAKE_COMPILER_IS_GNUCXX}) message(STATUS "Compiling with GCC") @@ -68,6 +68,12 @@ if(ENABLE_STRICT_COMPILER_SETTINGS) endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_STRICT_CXX_COMPILER_SETTINGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_STRICT_COMPILER_SETTINGS}") +else() + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_COMPILER_SETTINGS "-Wno-deprecated-declarations") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_COMPILER_SETTINGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_COMPILER_SETTINGS}") + endif() endif() if(CORE) diff --git a/Source/Thunder/PluginHost.cpp b/Source/Thunder/PluginHost.cpp index d53baa1bb..b512f68fe 100644 --- a/Source/Thunder/PluginHost.cpp +++ b/Source/Thunder/PluginHost.cpp @@ -899,7 +899,11 @@ 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 if (metaData.Slot[index].Job.IsSet() == false) { printf("\n"); } diff --git a/Source/Thunder/PluginServer.cpp b/Source/Thunder/PluginServer.cpp index a3c783ec3..677016362 100644 --- a/Source/Thunder/PluginServer.cpp +++ b/Source/Thunder/PluginServer.cpp @@ -497,7 +497,7 @@ namespace PluginHost { result = Core::ERROR_INPROGRESS; } else if ((currentState == IShell::state::DEACTIVATION) || (currentState == IShell::state::DESTROYED) || (currentState == IShell::state::HIBERNATED)) { result = Core::ERROR_ILLEGAL_STATE; - } else if ( (currentState == IShell::state::DEACTIVATED) ) { + } else if (currentState == IShell::state::DEACTIVATED) { result = Activate(why); currentState = State(); } diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index 529ced792..eaf3c3030 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -106,7 +106,8 @@ namespace PluginHost { ~WorkerPoolImplementation() override = default; public: - void Idle() { + void Idle() override + { // Could be that we can now drop the dynamic library... Core::ServiceAdministrator::Instance().FlushLibraries(); } @@ -867,7 +868,7 @@ namespace PluginHost { Unlock(); } - virtual Core::ProxyType Inbound(const string& identifier) + Core::ProxyType Inbound(const string& identifier) override { Core::ProxyType result; Lock(); @@ -4160,7 +4161,7 @@ namespace PluginHost { } // Whenever there is a state change on the link, it is reported here. - void StateChange() + void StateChange() override { TRACE(Activity, (_T("State change on [%d] to [%s]"), Id(), (IsSuspended() ? _T("SUSPENDED") : (IsUpgrading() ? _T("UPGRADING") : (IsWebSocket() ? _T("WEBSOCKET") : _T("WEBSERVER")))))); @@ -4417,7 +4418,11 @@ namespace PluginHost { std::list stackList; - ::DumpCallStack((ThreadId)index.Current().Id.Value(), stackList); +#ifdef __APPLE__ + ::DumpCallStack(reinterpret_cast(index.Current().Id.Value()), stackList); +#else + ::DumpCallStack(static_cast(index.Current().Id.Value()), stackList); +#endif PostMortemData::Callstack dump; dump.Id = index.Current().Id.Value(); diff --git a/Source/Thunder/SystemInfo.h b/Source/Thunder/SystemInfo.h index 74020f739..d19d43470 100644 --- a/Source/Thunder/SystemInfo.h +++ b/Source/Thunder/SystemInfo.h @@ -292,7 +292,7 @@ namespace PluginHost { END_INTERFACE_MAP public: - uint64_t TimeSync() const; + uint64_t TimeSync() const override; bool Set(const PluginHost::ISubSystem::ITime* info); inline bool Set(const uint64_t ticks) @@ -762,8 +762,8 @@ namespace PluginHost { return (_flags); } - string BuildTreeHash() const; - string Version() const; + string BuildTreeHash() const override; + string Version() const override; BEGIN_INTERFACE_MAP(SystemInfo) INTERFACE_ENTRY(PluginHost::ISubSystem) diff --git a/Source/ThunderPlugin/Process.cpp b/Source/ThunderPlugin/Process.cpp index 078c328d0..e8510e0ef 100644 --- a/Source/ThunderPlugin/Process.cpp +++ b/Source/ThunderPlugin/Process.cpp @@ -138,7 +138,8 @@ POP_WARNING() { Core::WorkerPool::Stop(); } - void Idle() { + void Idle() override + { // If we handled all pending requests, it is safe to "unload" Core::ServiceAdministrator::Instance().FlushLibraries(); } diff --git a/Source/com/Administrator.cpp b/Source/com/Administrator.cpp index df62df452..1515bf206 100644 --- a/Source/com/Administrator.cpp +++ b/Source/com/Administrator.cpp @@ -208,9 +208,9 @@ namespace RPC { _adminLock.Unlock(); if (result == true) { - TRACE_L3("Validated instance 0x%08" PRIxPTR " by administration", impl); + TRACE_L3("Validated instance 0x%08" PRId64 " by administration", impl); } else { - TRACE_L1("Failed to validate instance 0x%08" PRIxPTR " of interface 0x%08x", impl, id); + TRACE_L1("Failed to validate instance 0x%08" PRId64 " of interface 0x%08x", impl, id); } } } diff --git a/Source/com/Administrator.h b/Source/com/Administrator.h index 58d590b3f..664a4ba2f 100644 --- a/Source/com/Administrator.h +++ b/Source/com/Administrator.h @@ -189,7 +189,9 @@ namespace RPC { Stubs::iterator stub(_stubs.find(ACTUALINTERFACE::ID)); if (stub != _stubs.end()) { +PUSH_WARNING(DISABLE_WARNING_DELETE_INCOMPLETE) delete stub->second; +POP_WARNING() _stubs.erase(ACTUALINTERFACE::ID); } else { TRACE_L1("Failed to find a Stub for %d.", ACTUALINTERFACE::ID); diff --git a/Source/com/Communicator.h b/Source/com/Communicator.h index 249899d35..49050a626 100644 --- a/Source/com/Communicator.h +++ b/Source/com/Communicator.h @@ -661,7 +661,6 @@ namespace RPC { private: friend class ProcessShutdown; - class RemoteConnectionMap; class MonitorableProcess : public RemoteConnection, public IMonitorableProcess { public: @@ -1841,7 +1840,7 @@ POP_WARNING() // Lock event until Dispatch() sets it. return (_announceEvent.Lock(waitTime) == Core::ERROR_NONE); } - virtual void Dispatch(Core::IIPC& element); + void Dispatch(Core::IIPC& element) override; protected: void StateChange() override; diff --git a/Source/com/IUnknown.h b/Source/com/IUnknown.h index 522b8af85..32568dd80 100644 --- a/Source/com/IUnknown.h +++ b/Source/com/IUnknown.h @@ -52,10 +52,10 @@ namespace ProxyStub { inline uint16_t Length() const { return (3); } - virtual Core::IUnknown* Convert(void* incomingData) const { + virtual Core::IUnknown* Convert(void* incomingData) const { return (reinterpret_cast(incomingData)); } - virtual uint32_t InterfaceId() const { + virtual uint32_t InterfaceId() const { return (Core::IUnknown::ID); } virtual void Handle(const uint16_t index, Core::ProxyType& channel, Core::ProxyType& message); @@ -87,14 +87,15 @@ namespace ProxyStub { { return (_myHandlerCount + UnknownStub::Length()); } - virtual Core::IUnknown* Convert(void* incomingData) const + Core::IUnknown* Convert(void* incomingData) const override { return (reinterpret_cast(incomingData)); } - virtual uint32_t InterfaceId() const { + uint32_t InterfaceId() const override + { return (INTERFACE::ID); } - virtual void Handle(const uint16_t index, Core::ProxyType& channel, Core::ProxyType& message) + void Handle(const uint16_t index, Core::ProxyType& channel, Core::ProxyType& message) override { uint16_t baseNumber(UnknownStub::Length()); diff --git a/Source/com/IteratorType.h b/Source/com/IteratorType.h index 2e77b7bfc..b2c3638f5 100644 --- a/Source/com/IteratorType.h +++ b/Source/com/IteratorType.h @@ -85,8 +85,10 @@ namespace RPC { } public: +PUSH_WARNING(DISABLE_WARNING_INCONSISTENT_MISSING_OVERRIDE) virtual uint32_t AddRef() const = 0; virtual uint32_t Release() const = 0; +POP_WARNING() virtual bool IsValid() const override { diff --git a/Source/com/Messages.h b/Source/com/Messages.h index 8263c2cc2..71477a450 100644 --- a/Source/com/Messages.h +++ b/Source/com/Messages.h @@ -253,7 +253,7 @@ namespace RPC { if (parentInfo.empty() == false) { const size_t delimiter = std::min(parentInfo.find(','), parentInfo.length()); - if (exchangeId == ~0UL) { + if (exchangeId == static_cast(~0UL)) { exchangeId = Core::NumberType(parentInfo.c_str(), static_cast(delimiter)).Value(); } diff --git a/Source/core/ASN1.h b/Source/core/ASN1.h index 7bebd2fb8..2d9a03318 100644 --- a/Source/core/ASN1.h +++ b/Source/core/ASN1.h @@ -52,10 +52,12 @@ namespace Core { { if (_buffer != nullptr) { _buffer[0] = 1; +PUSH_WARNING(DISABLE_WARNING_CONSTANT_LOGICAL_OPERAND) _buffer[1] = (length & 0xFF); _buffer[2] = ((length >> 8) && 0xFF); _buffer[3] = (length & 0xFF); _buffer[4] = ((length >> 8) && 0xFF); +POP_WARNING() } } Buffer(const Buffer& copy) @@ -100,7 +102,9 @@ namespace Core { if (_buffer != nullptr) { _buffer[1] = (length & 0xFF); +PUSH_WARNING(DISABLE_WARNING_CONSTANT_LOGICAL_OPERAND) _buffer[2] = ((length >> 8) && 0xFF); +POP_WARNING() } } inline uint16_t Size() const diff --git a/Source/core/CMakeLists.txt b/Source/core/CMakeLists.txt index ddacb09c8..bc3380d76 100644 --- a/Source/core/CMakeLists.txt +++ b/Source/core/CMakeLists.txt @@ -244,6 +244,10 @@ if (NOT BUILD_SHARED_LIBS) ) endif() +if (APPLE) + target_compile_definitions( ${TARGET} PRIVATE __APPLE_USE_RFC_3542) +endif() + target_include_directories( ${TARGET} PUBLIC $ diff --git a/Source/core/DataElement.h b/Source/core/DataElement.h index 41251319b..10371da4f 100644 --- a/Source/core/DataElement.h +++ b/Source/core/DataElement.h @@ -285,7 +285,9 @@ namespace Core { m_MaxSize = (adjust < m_MaxSize ? (m_MaxSize - adjust) : 0); if (adjust != 0) { +PUSH_WARNING(DISABLE_WARNING_PEDANTIC) TRACE_L1("Aligning the memory buffer by %d bytes to %p !!!", adjust, m_Buffer); +POP_WARNING() } } } diff --git a/Source/core/DataElementFile.h b/Source/core/DataElementFile.h index 91ec9e9bd..af76d8d3e 100644 --- a/Source/core/DataElementFile.h +++ b/Source/core/DataElementFile.h @@ -112,7 +112,7 @@ namespace Core { protected: void Close(); - virtual void Reallocation(const uint64_t size); + void Reallocation(const uint64_t size) override; void ReopenMemoryMappedFile(); diff --git a/Source/core/DoorBell.cpp b/Source/core/DoorBell.cpp index 7729a1618..9ae5effa9 100644 --- a/Source/core/DoorBell.cpp +++ b/Source/core/DoorBell.cpp @@ -35,7 +35,11 @@ namespace Core { DoorBell::Connector::Connector(DoorBell& parent, const Core::NodeId& node) : _parent(parent) , _doorbell(node) +#ifdef __APPLE__ + , _sendSocket(::socket(_doorbell.Type(), SOCK_DGRAM, 0)) +#else , _sendSocket(::socket(_doorbell.Type(), SOCK_DGRAM|SOCK_CLOEXEC, 0)) +#endif , _receiveSocket(INVALID_SOCKET) , _registered(0) { @@ -46,6 +50,9 @@ namespace Core { } #else int flags = fcntl(_sendSocket, F_GETFL, 0) | O_NONBLOCK; +#ifdef __APPLE__ + flags |= O_CLOEXEC; +#endif if (fcntl(_sendSocket, F_SETFL, flags) != 0) { TRACE_L1("SendSocket:Error on port socket F_SETFL call. Error %d", errno); } @@ -72,7 +79,11 @@ namespace Core { bool DoorBell::Connector::Bind() const { if (_receiveSocket == INVALID_SOCKET) { +#ifdef __APPLE__ + _receiveSocket = ::socket(_doorbell.Type(), SOCK_DGRAM, 0); +#else _receiveSocket = ::socket(_doorbell.Type(), SOCK_DGRAM|SOCK_CLOEXEC, 0); +#endif #ifndef __WINDOWS__ // Check if domain path already exists, if so remove. @@ -109,7 +120,9 @@ namespace Core { } else { int flags = fcntl(_receiveSocket, F_GETFL, 0) | O_NONBLOCK; - +#ifdef __APPLE__ + flags |= O_CLOEXEC; +#endif if (fcntl(_receiveSocket, F_SETFL, flags) != 0) { TRACE_L1("Error on port socket F_SETFL call. Error %d", errno); ::close(_receiveSocket); diff --git a/Source/core/FileObserver.h b/Source/core/FileObserver.h index db22c7fac..835df69bd 100644 --- a/Source/core/FileObserver.h +++ b/Source/core/FileObserver.h @@ -28,8 +28,16 @@ namespace Thunder { namespace Core { -#ifdef __LINUX__ +#if defined(__APPLE__) || defined(__LINUX__) +#ifdef __APPLE__ +#include // for errno +#include // for O_RDONLY +#include // for strerror() +#include // for kqueue() etc. +#include // for close() +#else #include +#endif class FileSystemMonitor : public Core::IResource { public: @@ -91,8 +99,12 @@ class FileSystemMonitor : public Core::IResource { FileSystemMonitor() : _adminLock() +#ifdef __APPLE__ + , _notifyFd(kqueue()) +#else , _notifyFd(inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) , _files() +#endif , _observers() { } @@ -138,6 +150,40 @@ class FileSystemMonitor : public Core::IResource { } else { +#ifdef __APPLE__ + // The vnode monitor requires a file descriptor, so + // open the directory to get one. + int fileFd = open(filename.c_str(), O_EVTONLY); + if (fileFd > 0) + { + // Fill out the event structure. Store the name of the + // directory in the user data + struct kevent direvent; + EV_SET(&direvent, + fileFd, // identifier + EVFILT_VNODE, // filter + EV_ADD | EV_CLEAR | EV_ENABLE, // action flags + NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE, // filter flags + 0, // filter data + (void *)filename.c_str()); // user data + + // register the event + if (kevent(_notifyFd, &direvent, 1, NULL, 0, NULL) != -1) + { + _files.emplace(std::piecewise_construct, + std::forward_as_tuple(path), + std::forward_as_tuple(fileFd)); + _observers.emplace(std::piecewise_construct, + std::forward_as_tuple(fileFd), + std::forward_as_tuple(callback)); + + if (_files.size() == 1) { + // This is the first entry, lets start monitoring + Core::ResourceMonitor::Instance().Register(*this); + } + } + } +#else const uint32_t mask = Core::File(path).IsDirectory()? (IN_CREATE | IN_CLOSE_WRITE | IN_DELETE | IN_MOVE | IN_DELETE_SELF) : (IN_MODIFY | IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MOVE_SELF); @@ -155,6 +201,7 @@ class FileSystemMonitor : public Core::IResource { Core::ResourceMonitor::Instance().Register(*this); } } +#endif } _adminLock.Unlock(); @@ -180,9 +227,13 @@ class FileSystemMonitor : public Core::IResource { if (loop != _observers.end()) { loop->second.Unregister(callback); if (loop->second.HasCallbacks() == false) { +#ifdef __APPLE__ + ::close(index->second); //Stop monitoring this filepath +#else if (inotify_rm_watch(_notifyFd, index->second) < 0) { TRACE_L1(_T("Invoke of inotify_rm_watch failed")); } +#endif // Clear this index, we are no longer observing _files.erase(index); _observers.erase(loop); @@ -216,13 +267,34 @@ class FileSystemMonitor : public Core::IResource { { return (POLLIN); } +#if __APPLE__ + void Handle(const uint16_t events) override + { + if ((events & POLLIN) != 0) { + struct kevent event; + if(kevent(_notifyFd, NULL, 0, &event, 1, NULL) > 0) { + if (event.flags & EV_ERROR) + TRACE_L1(_T("Event error: %s"), strerror(event.data)); + else { + TRACE_L1(_T("Something was written in '%s'\n"), static_cast(event.udata)); + // Check if we have this entry.. + _adminLock.Lock(); + Observers::iterator loop = _observers.find(static_cast(event.ident)); + if (loop != _observers.end()) { + loop->second.Notify(); + } + _adminLock.Unlock(); + } + } + } + } +#else void Handle(const uint16_t events) override { if ((events & POLLIN) != 0) { uint8_t eventBuffer[(sizeof(struct inotify_event) + NAME_MAX + 1)]; int length; - do - { + do { length = ::read(_notifyFd, eventBuffer, sizeof(eventBuffer)); if (length >= static_cast(sizeof(struct inotify_event))) { @@ -258,6 +330,7 @@ class FileSystemMonitor : public Core::IResource { } while (length > 0); } } +#endif private: Core::CriticalSection _adminLock; diff --git a/Source/core/IPCConnector.h b/Source/core/IPCConnector.h index 73c2ace83..f16cb8b20 100644 --- a/Source/core/IPCConnector.h +++ b/Source/core/IPCConnector.h @@ -449,15 +449,15 @@ POP_WARNING() { return (_response.Package()); } - virtual uint32_t Label() const + uint32_t Label() const override { return (IDENTIFIER); } - virtual ProxyType IParameters() + ProxyType IParameters() override { return (ProxyType(_parameters, _parameters)); } - virtual ProxyType IResponse() + ProxyType IResponse() override { return (ProxyType(_response, _response)); } diff --git a/Source/core/JSON.h b/Source/core/JSON.h index bc93bd1bd..10d7c5b15 100644 --- a/Source/core/JSON.h +++ b/Source/core/JSON.h @@ -1280,7 +1280,7 @@ namespace Core { if (_strValue.empty() == true) { char str[16]; - std::sprintf(str, "%g", _value); + std::snprintf(str, sizeof(str), "%g", _value); const_cast(this)->_strValue = str; } @@ -2324,7 +2324,7 @@ namespace Core { return ((_length > 0) && ((_state & SET) != 0)); } - bool IsNull() const + bool IsNull() const override { return ((_state & UNDEFINED) != 0); } @@ -4738,7 +4738,7 @@ namespace Core { return (Iterator(_elements)); } - void Clear() + void Clear() override { Reset(); _elements.clear(); diff --git a/Source/core/JSONRPC.h b/Source/core/JSONRPC.h index d98e30d01..77d9967ce 100644 --- a/Source/core/JSONRPC.h +++ b/Source/core/JSONRPC.h @@ -96,7 +96,7 @@ namespace Core { } public: - void Clear() + void Clear() override { Code.Clear(); Text.Clear(); @@ -369,7 +369,7 @@ namespace Core { return (val); } - void Clear() + void Clear() override { JSONRPC = DefaultVersion; Id.Clear(); diff --git a/Source/core/MessageStore.cpp b/Source/core/MessageStore.cpp index ad15dc551..d42bc63aa 100644 --- a/Source/core/MessageStore.cpp +++ b/Source/core/MessageStore.cpp @@ -52,7 +52,8 @@ ENUM_CONVERSION_END(Core::Messaging::Metadata::type) _adminLock.Lock(); while (_controlList.size() > 0) { - TRACE_L1(_T("MessageControl %s, size = %u was not disposed before"), typeid(*_controlList.front()).name(), static_cast(_controlList.size())); + VARIABLE_IS_NOT_USED auto& control = *_controlList.front(); + TRACE_L1(_T("MessageControl %s, size = %u was not disposed before"), typeid(control).name(), static_cast(_controlList.size())); _controlList.front()->Destroy(); } diff --git a/Source/core/Netlink.cpp b/Source/core/Netlink.cpp index 58ca83f66..b9a2a713e 100644 --- a/Source/core/Netlink.cpp +++ b/Source/core/Netlink.cpp @@ -17,6 +17,7 @@ * limitations under the License. */ +#if !defined (__WINDOWS__) && !defined(__APPLE__) #include #include "Netlink.h" @@ -239,3 +240,4 @@ namespace Core { } } } // namespace Thunder::Core +#endif //!defined (__WINDOWS__) && !defined(__APPLE__) diff --git a/Source/core/Netlink.h b/Source/core/Netlink.h index c84bdde5e..a6b20dbeb 100644 --- a/Source/core/Netlink.h +++ b/Source/core/Netlink.h @@ -20,7 +20,7 @@ #ifndef NETLINK_MESSAGE_H_ #define NETLINK_MESSAGE_H_ -#ifndef __WINDOWS__ +#if !defined (__WINDOWS__) && !defined(__APPLE__) #include "Module.h" #include "NodeId.h" diff --git a/Source/core/NetworkInfo.cpp b/Source/core/NetworkInfo.cpp index 4dc67f788..a297299d6 100644 --- a/Source/core/NetworkInfo.cpp +++ b/Source/core/NetworkInfo.cpp @@ -33,11 +33,13 @@ #include #include #pragma comment(lib, "iphlpapi.lib") +#elif defined(__APPLE__) +#include +#include #elif defined(__POSIX__) #include #include #include -#include #include #include #include @@ -45,15 +47,11 @@ #include #endif -#ifdef __APPLE__ -#include -#endif - namespace Thunder { namespace Core { -#ifdef __WINDOWS__ +#if defined(__WINDOWS__) /* Note: could also use malloc() and free() */ #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) @@ -536,7 +534,197 @@ namespace Core { return (Core::ERROR_BAD_REQUEST); } -#elif defined(__POSIX__) +#elif defined(__APPLE__) + using AdapterAddresses = std::vector; + using Adapters = std::map; + + inline void ConvertMACToString(const uint8_t address[], const uint8_t length, const char delimiter, string& output) + { + for (uint8_t i = 0; i < length; i++) { + // Reason for the low-level approch is performance. + // In stead of using string operations, we know that each byte exists of 2 nibbles, + // lets just translate these nibbles to Hexadecimal numbers and add them to the output. + // This saves a setup of several string manipulation operations. + uint8_t highNibble = ((address[i] & 0xF0) >> 4); + uint8_t lowNibble = (address[i] & 0x0F); + if ((i != 0) && (delimiter != '\0')) { + output += delimiter; + } + output += static_cast(highNibble + (highNibble >= 10 ? ('A' - 10) : '0')); + output += static_cast(lowNibble + (lowNibble >= 10 ? ('A' - 10) : '0')); + } + } + + static uint8_t LoadAdapterInfo(const uint16_t adapterIndex, AdapterAddresses& addresses) + { + struct ifaddrs *interfaces; + Adapters adapters; + if (!getifaddrs(&interfaces)) { + + struct ifaddrs* index = interfaces->ifa_next; + while (index != nullptr) { + + Adapters::iterator adapterIndex = adapters.find(index->ifa_name); + if (adapterIndex == adapters.end()) { + AdapterAddresses addresses; + addresses.push_back(index); + adapters.emplace(std::piecewise_construct, std::forward_as_tuple(index->ifa_name), std::forward_as_tuple(addresses)); + } else { + AdapterAddresses& addresses = adapterIndex->second; + addresses.push_back(index); + } + index = index->ifa_next; + } + + if (adapters.size() > 0) { + if (adapterIndex < adapters.size()) { + Adapters::iterator index = adapters.begin(); + std::advance(index, adapterIndex); + addresses = index->second; + } + } + } + return adapters.size(); + } + + IPV4AddressIterator::IPV4AddressIterator(const uint16_t adapter) + : _adapter(adapter) + { + } + + IPNode IPV4AddressIterator::Address() const + { + IPNode result; + AdapterAddresses addresses; + LoadAdapterInfo(_adapter, addresses); + + if (addresses.size() > 0) { + for (auto& address: addresses) { + if (address->ifa_addr->sa_family == static_cast(AF_INET)) { + result = IPNode(NodeId(*reinterpret_cast(address->ifa_addr)), 0); + break; + } else if (address->ifa_addr->sa_family == static_cast(AF_INET6)) { + result = IPNode(NodeId(*reinterpret_cast(address->ifa_addr)), 0); + } + } + } + + return (result); + } + + uint16_t AdapterIterator::Count() const + { + AdapterAddresses addresses; + uint8_t adapterCount = LoadAdapterInfo(_index, addresses); + return adapterCount; + } + + string AdapterIterator::Name() const + { + ASSERT(IsValid()); + string result(_T("Unknown")); + AdapterAddresses addresses; + LoadAdapterInfo(_index, addresses); + + if (addresses.size() > 0) { + ToString(addresses[0]->ifa_name, result); + } + + return (result); + } + + string AdapterIterator::MACAddress(const char delimiter) const + { + ASSERT(IsValid()); + string result(_T("0:0:0:0")); + AdapterAddresses addresses; + LoadAdapterInfo(_index, addresses); + + if (addresses.size() > 0) { + for (auto& address: addresses) { + if (address->ifa_addr->sa_family == AF_LINK && address->ifa_addr->sa_len >= 15) { + uint8_t MAC[6]; + memcpy(MAC, &address->ifa_addr->sa_data[9], 6); + ConvertMACToString(MAC, sizeof(MAC), delimiter, result); + } + } + } + + return (result); + } + + void AdapterIterator::MACAddress(uint8_t buffer[], const uint8_t length) const + { + ASSERT(IsValid()); + AdapterAddresses addresses; + LoadAdapterInfo(_index, addresses); + + if (addresses.size() > 0) { + for (auto& address: addresses) { + if (address->ifa_addr->sa_family == AF_LINK && address->ifa_addr->sa_len >= 15) { + memcpy(buffer, &address->ifa_addr->sa_data[9], 6); + } + } + } + } + + uint32_t AdapterIterator::Up(const bool) + { + // TODO: Implement + ASSERT(IsValid()); + + return (Core::ERROR_NONE); + } + + bool AdapterIterator::IsUp() const + { + // TODO: Implement + ASSERT(false); + + return (false); + } + + bool AdapterIterator::IsRunning() const + { + return (true); + } + + uint32_t AdapterIterator::MACAddress(const uint8_t[6]) { + return (Core::ERROR_NOT_SUPPORTED); + } + + uint32_t AdapterIterator::Add(const IPNode& address) + { + uint32_t result = Core::ERROR_NONE; + return (result); + } + + uint32_t AdapterIterator::Delete(const IPNode& address) + { + + uint32_t result = Core::ERROR_NONE; + return (result); + } + + uint32_t AdapterIterator::Gateway(const IPNode& network, const NodeId& gateway) + { + + //TODO: Needs implementation + ASSERT(false); + + return (Core::ERROR_BAD_REQUEST); + } + + uint32_t AdapterIterator::Broadcast(const Core::NodeId& address) + { + + //TODO: Needs implementation + ASSERT(false); + + return (Core::ERROR_BAD_REQUEST); + } + +#elif defined(__LINUX__) template class IPAddressModifyType : public Netlink { @@ -1708,14 +1896,14 @@ namespace Core { } uint32_t AdapterObserver::Open() { -#ifndef __WINDOWS__ +#if !defined(__WINDOWS__) && !defined(__APPLE__) IPNetworks::Instance().Register(_callback); #endif return (Core::ERROR_NONE); } uint32_t AdapterObserver::Close() { -#ifndef __WINDOWS__ +#if !defined(__WINDOWS__) && !defined(__APPLE__) IPNetworks::Instance().Unregister(_callback); #endif return (Core::ERROR_NONE); diff --git a/Source/core/NetworkInfo.h b/Source/core/NetworkInfo.h index 25dcef81e..43a612d9f 100644 --- a/Source/core/NetworkInfo.h +++ b/Source/core/NetworkInfo.h @@ -209,7 +209,7 @@ namespace Core { INotification* _callback; }; -#ifdef __WINDOWS__ +#if defined(__WINDOWS__) || defined(__APPLE__) class EXTERNAL IPV4AddressIterator { public: @@ -310,6 +310,7 @@ namespace Core { uint16_t _section3; }; +#if defined(__WINDOWS__) class EXTERNAL IPV6AddressIterator { public: inline IPV6AddressIterator() @@ -408,6 +409,9 @@ namespace Core { uint16_t _section3; }; +#else + using IPV6AddressIterator = IPV4AddressIterator; +#endif class EXTERNAL AdapterIterator { public: diff --git a/Source/core/NodeId.h b/Source/core/NodeId.h index 210385809..4acfec44d 100644 --- a/Source/core/NodeId.h +++ b/Source/core/NodeId.h @@ -95,19 +95,15 @@ namespace Core { TYPE_EMPTY = 0xFF }; - -#ifdef __WINDOWS__ +#if defined(__WINDOWS__) using address_family_t = ADDRESS_FAMILY; #else using address_family_t = sa_family_t; #endif - union SocketInfo { -#ifdef __WINDOWS__ - address_family_t Family; -#elif defined(__APPLE__) - struct __sockaddr_header saddr_hdr; +#if defined(__APPLE__) + struct sockaddr saddr_hdr; #else address_family_t Family; #endif @@ -208,9 +204,9 @@ namespace Core { NodeId(const struct in6_addr& rInfo, const uint32_t protocol = 0); #ifndef __WINDOWS__ NodeId(const struct sockaddr_un& rInfo, const uint16_t access = ~0); -#ifndef __APPLE__ +#ifndef __APPLE__ NodeId(const uint32_t destination, const pid_t pid, const uint32_t groups); - NodeId(const struct sockaddr_ll& rInfo); + NodeId(const struct sockaddr_ll& rInfo); NodeId(const uint16_t interfaceIndex, const uint16_t protocol, const uint8_t pkgtype, const uint8_t haType, const uint8_t length, const uint8_t* address); NodeId(const TCHAR interfaceName[], const uint16_t protocol, const uint8_t pkgType, const uint8_t haType, const uint8_t length, const uint8_t* address); #endif diff --git a/Source/core/Number.h b/Source/core/Number.h index ac5cb7e60..15ae86e0d 100644 --- a/Source/core/Number.h +++ b/Source/core/Number.h @@ -1030,8 +1030,7 @@ namespace Core { public: using BASE = BitArrayBaseType>; using T = typename BASE::T; - - BitArrayFlexType(uint8_t size = 0, T initial = 0) + BitArrayFlexType(uint8_t size = 0, VARIABLE_IS_NOT_USED T initial = 0) { Reset(size); } diff --git a/Source/core/Portability.h b/Source/core/Portability.h index 1f75d6ee6..765c2e255 100644 --- a/Source/core/Portability.h +++ b/Source/core/Portability.h @@ -187,6 +187,8 @@ #define DISABLE_WARNING_PEDANTIC #define DISABLE_WARNING_OVERLOADED_VIRTUALS #define DISABLE_WARNING_CONSTANT_LOGICAL_OPERAND +#define DISABLE_WARNING_DELETE_INCOMPLETE +#define DISABLE_WARNING_INCONSISTENT_MISSING_OVERRIDE #else #define DISABLE_WARNING_CONDITIONAL_EXPRESSION_IS_CONSTANT @@ -215,6 +217,8 @@ #define DISABLE_WARNING_OVERLOADED_VIRTUALS PUSH_WARNING_ARG_("-Woverloaded-virtual") #define DISABLE_WARNING_CONVERSION_TO_GREATERSIZE PUSH_WARNING_ARG_("-Wint-to-pointer-cast") #define DISABLE_WARNING_CONSTANT_LOGICAL_OPERAND PUSH_WARNING_ARG_("-Wconstant-logical-operand") +#define DISABLE_WARNING_DELETE_INCOMPLETE PUSH_WARNING_ARG_("-Wdelete-incomplete") +#define DISABLE_WARNING_INCONSISTENT_MISSING_OVERRIDE PUSH_WARNING_ARG_("-Winconsistent-missing-override") #endif #endif @@ -425,6 +429,7 @@ typedef std::string string; #define POLLRDHUP 0x2000 #endif +#define SOCK_CLOEXEC 0 #define __APPLE_USE_RFC_3542 extern "C" EXTERNAL void* mremap(void* old_address, size_t old_size, size_t new_size, int flags); @@ -470,6 +475,7 @@ uint64_t ntohll(const uint64_t& value); #define _tcsrchr wcsrchr #define _tcsftime wcsftime #define _stprintf swprintf +#define _stnprintf swprintf #define _tcscpy wcscpy #define _tcsncpy wcsncpy @@ -499,6 +505,7 @@ uint64_t ntohll(const uint64_t& value); #define _tcsrchr strrchr #define _tcsftime strftime #define _stprintf sprintf +#define _stnprintf snprintf #define _tcscpy strcpy #define _tcsncpy strncpy diff --git a/Source/core/Process.h b/Source/core/Process.h index f9e5f9776..d582397f6 100644 --- a/Source/core/Process.h +++ b/Source/core/Process.h @@ -459,7 +459,7 @@ namespace Core { } #endif -#ifdef __LINUX__ +#ifdef __POSIX__ uint16_t size = parameters.BlockSize(); _parameters = ::malloc(size); _argc = parameters.Block(_parameters, size); @@ -473,10 +473,10 @@ namespace Core { stderrfd[1] = -1; /* Create the pipe and set non-blocking on the readable end. */ - if ((_stdin == -1) && (pipe2(stdinfd, O_CLOEXEC) == 0) && (pipe2(stdoutfd, O_CLOEXEC) == 0) && (pipe2(stderrfd, O_CLOEXEC) == 0)) { + if ((_stdin == -1) && (pipe(stdinfd) == 0) && (pipe(stdoutfd) == 0) && (pipe(stderrfd) == 0)) { // int flags = ( fcntl(p[0], F_GETFL, 0) & (~O_NONBLOCK) ); - int input = (fcntl(stdinfd[1], F_GETFL, 0) | O_NONBLOCK); - int output = (fcntl(stdoutfd[0], F_GETFL, 0) | O_NONBLOCK); + int input = (fcntl(stdinfd[1], F_GETFL, 0) | O_NONBLOCK | O_CLOEXEC); + int output = (fcntl(stdoutfd[0], F_GETFL, 0) | O_NONBLOCK | O_CLOEXEC); if ((fcntl(stdinfd[1], F_SETFL, input) != 0) || (fcntl(stdoutfd[0], F_SETFL, output) != 0) || (fcntl(stderrfd[0], F_SETFL, output) != 0)) { _stdin = 0; diff --git a/Source/core/ProcessInfo.cpp b/Source/core/ProcessInfo.cpp index dde1c4c69..c29dc469a 100644 --- a/Source/core/ProcessInfo.cpp +++ b/Source/core/ProcessInfo.cpp @@ -28,7 +28,9 @@ #include #include #include +#ifndef __APPLE__ #include +#endif #include #endif @@ -243,7 +245,7 @@ namespace Core { , _current() , _index(0) { -#ifndef __WINDOWS__ +#if !defined(__WINDOWS__) && !defined(__APPLE__) FindChildren(_pids, [=](const uint32_t, const uint32_t) { return true; }); #endif Reset(); @@ -255,7 +257,7 @@ namespace Core { , _current() , _index(0) { -#ifndef __WINDOWS__ +#if !defined(__WINDOWS__) && !defined(__APPLE__) FindChildren(_pids, [=](const process_t foundparentPID, const uint32_t childPID) { bool accept = false; char fullname[PATH_MAX]; @@ -279,7 +281,7 @@ namespace Core { , _current() , _index(0) { -#ifndef __WINDOWS__ +#if !defined(__WINDOWS__) && !defined(__APPLE__) FindChildren(_pids, [=](const process_t foundparentPID, const uint32_t childPID) { bool accept = false; @@ -310,9 +312,11 @@ namespace Core { } } #else +#ifndef __APPLE__ FindChildren(_pids, [=](const uint32_t foundparentPID, const uint32_t) { return parentPID == foundparentPID; }); +#endif #endif Reset(); @@ -509,9 +513,11 @@ namespace Core { if (GetCurrentProcessId() == _pid) { } #else +#ifndef __APPLE__ //No straight forward way to set process name in OSX if (static_cast(::getpid()) == _pid) { prctl(PR_SET_NAME, name.c_str(), 0, 0, 0, 0); } +#endif #endif } string ProcessInfo::Executable() const @@ -527,7 +533,7 @@ namespace Core { std::list ProcessInfo::CommandLine() const { char procPath[PATH_MAX]; - sprintf(procPath, "/proc/%u/cmdline", _pid); + snprintf(procPath, sizeof(procPath), "/proc/%u/cmdline", _pid); std::list output; @@ -577,7 +583,7 @@ namespace Core { /* static */ void ProcessInfo::FindByName(const string& name, const bool exact, std::list& processInfos) { -#ifndef __WINDOWS__ +#if !defined(__WINDOWS__) && !defined(__APPLE__) std::list pidList; FindPid(name, exact, pidList); @@ -619,7 +625,7 @@ namespace Core { void ProcessCurrent::SupplementryGroups(const string& userName) { -#ifndef __WINDOWS__ +#if !defined(__WINDOWS__) && !defined(__APPLE__) struct passwd* pwd = getpwnam(userName.c_str()); if (pwd != nullptr) { int numberOfGroups = 0; diff --git a/Source/core/Proxy.h b/Source/core/Proxy.h index e0a3c5313..4647c532c 100644 --- a/Source/core/Proxy.h +++ b/Source/core/Proxy.h @@ -176,10 +176,12 @@ namespace Thunder { const void* result = Alignment(alignof(TYPE), data); return (reinterpret_cast(result)); } +PUSH_WARNING(DISABLE_WARNING_INCONSISTENT_MISSING_OVERRIDE) inline void Clear() { __Clear(); } +POP_WARNING() inline bool IsInitialized() const { return (__IsInitialized()); diff --git a/Source/core/ResourceMonitor.h b/Source/core/ResourceMonitor.h index a7a93dae5..8e8214c27 100644 --- a/Source/core/ResourceMonitor.h +++ b/Source/core/ResourceMonitor.h @@ -25,6 +25,22 @@ #include "Thread.h" #include "Trace.h" #include "Timer.h" +#include "NodeId.h" + +#ifdef __WINDOWS__ +#include +#pragma comment(lib, "ws2_32.lib") +#endif + +#ifdef __UNIX__ +#define SOCKET signed int +#define SOCKET_ERROR static_cast(-1) +#define INVALID_SOCKET static_cast(-1) +#include +#include +#include +#include +#endif namespace Thunder { @@ -198,7 +214,7 @@ namespace Core { info.events = _descriptorArray[position + 1].revents; char procfn[64]; - sprintf(procfn, "/proc/self/fd/%d", info.descriptor); + snprintf(procfn, sizeof(procfn), "/proc/self/fd/%d", info.descriptor); size_t len = readlink(procfn, info.filename, sizeof(info.filename) - 1); info.filename[len] = '\0'; @@ -258,10 +274,10 @@ namespace Core { #ifdef __APPLE__ int data = 0; - ::sendto(_signalDescriptor + ::sendto(_signalDescriptor, & data, sizeof(data), 0, - _signalNode, + static_cast(_signalNode), _signalNode.Size()); #elif defined(__LINUX__) _monitor->Signal(SIGUSR2); @@ -301,7 +317,39 @@ namespace Core { { } - #ifdef __LINUX__ + bool SetNonBlocking(signed int socket) + { +#ifdef __WINDOWS__ + unsigned long l_Value = 1; + if (ioctlsocket(socket, FIONBIO, &l_Value) != 0) { + TRACE_L1("Error on port socket NON_BLOCKING call. Error %d", ::WSAGetLastError()); + } + else { + return (true); + } +#endif + +#ifdef __POSIX__ + if (fcntl(socket, F_SETOWN, getpid()) == -1) { + TRACE_L1("Setting Process ID failed. <%d>", errno); + } + else { + int flags = fcntl(socket, F_GETFL, 0) | O_NONBLOCK; + + if (fcntl(socket, F_SETFL, flags) != 0) { + TRACE_L1("Error on port socket F_SETFL call. Error %d", errno); + } + else { + return (true); + } + } +#endif + + return (false); + } + + public: +#ifdef __LINUX__ uint32_t Initialize() { #ifdef __APPLE__ @@ -312,11 +360,13 @@ namespace Core { _signalDescriptor = -1; TRACE_L1("Error on etting socket to non blocking. Error %d", errno); } else { - char* file = mktemp("/tmp/ResourceMonitor.XXXXXX"); - + char fileNameTemplate[] = "/tmp/ResourceMonitor.XXXXXX"; +PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) + char* file = mktemp(fileNameTemplate); +POP_WARNING() // Do we need to find something to bind to or is it pre-destined _signalNode = Core::NodeId(file); - if (::bind(_signalDescriptor, _signalNode, _signalNode.Size()) != 0) { + if (::bind(_signalDescriptor, static_cast(_signalNode), _signalNode.Size()) != 0) { _signalDescriptor = -1; } } diff --git a/Source/core/SocketPort.cpp b/Source/core/SocketPort.cpp index 26f1fa0c0..88cd6f114 100644 --- a/Source/core/SocketPort.cpp +++ b/Source/core/SocketPort.cpp @@ -41,6 +41,7 @@ #ifdef __APPLE__ #include +#include #elif defined(__LINUX__) #include #include @@ -62,6 +63,13 @@ #define __ERROR_CONNRESET__ WSAECONNRESET #define __ERROR_NETWORK_UNREACHABLE__ WSAENETUNREACH PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) +#else + +#ifdef __APPLE__ +#define IPV6_PACKAGE_TYPE IPV6_RECVPKTINFO +#else +#define IPV6_PACKAGE_TYPE IPV6_PKTINFO +#endif #endif namespace Thunder { @@ -238,7 +246,7 @@ namespace Thunder { interfaceId = info->ipi_ifindex; break; } - else if ((cmsg->cmsg_level == IPPROTO_IPV6) && (cmsg->cmsg_type == IPV6_PKTINFO) && (remote->sa_family == AF_INET6)) { + else if ((cmsg->cmsg_level == IPPROTO_IPV6) && (cmsg->cmsg_type == IPV6_PACKAGE_TYPE) && (remote->sa_family == AF_INET6)) { const struct in6_pktinfo* info = reinterpret_castCMSG_DATA(cmsg); interfaceId = info->ipi6_ifindex; break; @@ -811,15 +819,31 @@ namespace Thunder { } #endif +#ifdef __APPLE__ + { + int flags = fcntl(l_Result, F_GETFL, 0) | O_CLOEXEC; + + if (fcntl(l_Result, F_SETFL, flags) != 0) { + TRACE_L1("ConstructSocket:Error on port socket F_SETFL call. Error %d", errno); + } + + } +#endif + #ifndef __WINDOWS__ // See if we need to bind to a specific interface. if ((l_Result != INVALID_SOCKET) && (specificInterface.empty() == false)) { struct ifreq interface; +#ifdef __APPLE__ + strncpy(interface.ifr_name, specificInterface.c_str(), IFNAMSIZ - 1); + int index = if_nametoindex(interface.ifr_name); + if (::setsockopt(l_Result, IPPROTO_IP, IP_BOUND_IF, (const char*)&index, sizeof(index)) < 0) { +#else strncpy(interface.ifr_ifrn.ifrn_name, specificInterface.c_str(), IFNAMSIZ - 1); if (::setsockopt(l_Result, SOL_SOCKET, SO_BINDTODEVICE, (const char*)&interface, sizeof(interface)) < 0) { - +#endif TRACE_L1("Error binding socket to an interface. Error %d", __ERRORRESULT__); ::close(l_Result); @@ -838,7 +862,7 @@ namespace Thunder { } } else if (localNode.Type() == NodeId::TYPE_IPV6) { - if (::setsockopt(l_Result, IPPROTO_IPV6, IPV6_PKTINFO, (const char*)&optval, sizeof(optval)) != 0) { + if (::setsockopt(l_Result, IPPROTO_IPV6, IPV6_PACKAGE_TYPE, (const char*)&optval, sizeof(optval)) != 0) { TRACE_L1("Error getting additional info on received packages. Error %d", __ERRORRESULT__); } } @@ -1298,7 +1322,7 @@ namespace Thunder { socklen_t size = sizeof(address); SOCKET result; -#ifdef __WINDOWS__ +#if defined(__WINDOWS__) || defined(__APPLE__) if ((result = ::accept(m_Socket, (struct sockaddr*)&address, &size)) != SOCKET_ERROR) { #else if ((result = ::accept4(m_Socket, (struct sockaddr*)&address, &size, SOCK_CLOEXEC)) != SOCKET_ERROR) { diff --git a/Source/core/SocketPort.h b/Source/core/SocketPort.h index 006d32a69..431adae9a 100644 --- a/Source/core/SocketPort.h +++ b/Source/core/SocketPort.h @@ -356,14 +356,6 @@ namespace Thunder { } ~SocketStream() override = default; - - public: - // Methods to extract and insert data into the socket buffers - virtual uint16_t SendData(uint8_t* dataFrame, const uint16_t maxSendSize) = 0; - virtual uint16_t ReceiveData(uint8_t* dataFrame, const uint16_t receivedSize) = 0; - - // Signal a state change, Opened, Closed or Accepted - virtual void StateChange() = 0; }; class EXTERNAL SocketDatagram : public SocketPort { @@ -396,14 +388,6 @@ namespace Thunder { ~SocketDatagram() override { } - - public: - // Methods to extract and insert data into the socket buffers - virtual uint16_t SendData(uint8_t* dataFrame, const uint16_t maxSendSize) = 0; - virtual uint16_t ReceiveData(uint8_t* dataFrame, const uint16_t receivedSize) = 0; - - // Signal a state change, Opened, Closed or Accepted - virtual void StateChange() = 0; }; class EXTERNAL SocketListner { @@ -434,21 +418,21 @@ namespace Thunder { { SocketPort::LocalNode(localNode); } - virtual uint16_t SendData(uint8_t* /* dataFrame */, const uint16_t /* maxSendSize */) + uint16_t SendData(uint8_t* /* dataFrame */, const uint16_t /* maxSendSize */) override { // This should not happen on this socket !!!!! ASSERT(false); return (0); } - virtual uint16_t ReceiveData(uint8_t* /* dataFrame */, const uint16_t /* receivedSize */) + uint16_t ReceiveData(uint8_t* /* dataFrame */, const uint16_t /* receivedSize */) override { // This should not happen on this socket !!!!! ASSERT(false); return (0); } - virtual void StateChange() + void StateChange() override { SOCKET newClient; NodeId remoteId; diff --git a/Source/core/Sync.cpp b/Source/core/Sync.cpp index a1c9d854e..43f2bd06f 100644 --- a/Source/core/Sync.cpp +++ b/Source/core/Sync.cpp @@ -47,13 +47,20 @@ #include #include #endif +#ifdef __APPLE__ +#include +#include +#include +#include +#include +#endif //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // GLOBAL INTERLOCKED METHODS //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- -#if BUILD_TESTS +#if defined(BUILD_TESTS) && !defined(__APPLE__) // TODO: What is going on here?? // https://github.com/google/googletest/issues/2328 #include @@ -425,7 +432,6 @@ namespace Core { if (nTime == Core::infinite) { return (Lock()); } else { - // See if we can check the state. pthread_mutex_lock(&m_syncAdminLock); diff --git a/Source/core/SystemInfo.cpp b/Source/core/SystemInfo.cpp index 78d035b98..40028671b 100644 --- a/Source/core/SystemInfo.cpp +++ b/Source/core/SystemInfo.cpp @@ -33,8 +33,8 @@ #include #ifdef __APPLE__ -#import -#import +#include +#include #include #include #elif defined(__LINUX__) @@ -300,8 +300,11 @@ namespace Core { mib[1] = KERN_BOOTTIME; length = sizeof(time); sysctl(mib, 2, &time, &length, nullptr, 0); - - m_uptime = (Core::Time::Now().Ticks() - Core::Time(time).Ticks()) / (Core::Time::TicksPerMillisecond * 1000); + + struct timespec ts; + ts.tv_sec = time.tv_sec; + ts.tv_nsec = time.tv_usec * Core::Time::NanoSecondsPerMicroSecond; + m_uptime = (Core::Time::Now().Ticks() - Core::Time(ts).Ticks()) / (Core::Time::TicksPerMillisecond * 1000); mach_msg_type_number_t count = HOST_VM_INFO_COUNT; if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count) != KERN_SUCCESS) { diff --git a/Source/core/Thread.cpp b/Source/core/Thread.cpp index fec3cc738..56a659661 100644 --- a/Source/core/Thread.cpp +++ b/Source/core/Thread.cpp @@ -53,6 +53,9 @@ namespace Core { #else , m_hThreadInstance() , m_ThreadId(0) +#ifdef __POSIX__ + , m_threadName("") +#endif #endif { TRACE_L5("Constructor Thread <%p>", (this)); @@ -71,6 +74,10 @@ namespace Core { // then it is up to us. if (m_hThreadInstance == nullptr) #endif + std::string convertedName; + if (threadName != nullptr) { + Core::ToString(threadName, convertedName); + } #ifdef __POSIX__ int err; @@ -86,8 +93,10 @@ namespace Core { ASSERT(err == 0); } + m_threadName = convertedName; // If there is no thread, the "new" thread can also not free the destructor, // then it is up to us. + if ((err != 0) || (pthread_create(&m_hThreadInstance, &attr, (void* (*)(void*))Thread::StartThread, this) != 0)) #endif { @@ -99,16 +108,13 @@ namespace Core { #ifdef __POSIX__ err = pthread_attr_destroy(&attr); ASSERT(err == 0); - m_ThreadId = m_hThreadInstance; -#endif - - if (threadName != nullptr) { - std::string convertedName; - Core::ToString(threadName, convertedName); - +#else + if (convertedName.empty() != true) { ThreadName(convertedName.c_str()); } +#endif + } Thread::~Thread() { @@ -138,13 +144,16 @@ POP_WARNING() #ifdef __WINDOWS__ void Thread::StartThread(Thread* cClassPointer) -#endif - -#ifdef __POSIX__ - void* Thread::StartThread(Thread* cClassPointer) +#else + void* Thread::StartThread(Thread* cClassPointer) #endif { + #ifdef __POSIX__ + if (cClassPointer->ThreadName().empty() != true) { + cClassPointer->ThreadName(cClassPointer->ThreadName().c_str()); + } + // It is the responsibility of the main app to make sure all threads created are stopped properly. // No jumping and bailing out without a proper closure !!!! sigset_t mask; @@ -438,14 +447,22 @@ POP_WARNING() } __except (EXCEPTION_EXECUTE_HANDLER) { } #endif // __DEBUG__ +#else +#ifdef __APPLE__ + int rc = pthread_setname_np(threadName); #else int rc = pthread_setname_np(m_hThreadInstance, threadName); +#endif if (rc == ERANGE) { // name too long - max 16 chars allowed char truncName[16]; strncpy(truncName, threadName, sizeof(truncName)); truncName[15] = '\0'; +#ifdef __APPLE__ + pthread_setname_np(truncName); +#else pthread_setname_np(m_hThreadInstance, truncName); +#endif } #endif // __WINDOWS__ } diff --git a/Source/core/Thread.h b/Source/core/Thread.h index 6f92bd4d3..d9f71a00b 100644 --- a/Source/core/Thread.h +++ b/Source/core/Thread.h @@ -242,6 +242,12 @@ namespace Core { virtual uint32_t Worker() = 0; void Terminate(); bool State(thread_state enumState); +#ifdef __POSIX__ + inline string ThreadName() const + { + return m_threadName; + } +#endif void ThreadName(const char* threadName); inline void SignalTermination() @@ -284,6 +290,9 @@ namespace Core { ::ThreadId m_ThreadId; static uint32_t _defaultStackSize; +#ifdef __POSIX__ + string m_threadName; +#endif #ifdef __CORE_EXCEPTION_CATCHING__ static IExceptionCallback* _exceptionHandler; diff --git a/Source/core/Time.cpp b/Source/core/Time.cpp index 459ddcc68..a738efd16 100644 --- a/Source/core/Time.cpp +++ b/Source/core/Time.cpp @@ -20,6 +20,7 @@ #include "Time.h" #include "Number.h" #include +#include namespace { // Start day of NTP time as days past the imaginary date 12/1/1 BC. @@ -816,11 +817,11 @@ namespace Core { SYSTEMTIME convertedTime; SystemTimeToTzSpecificLocalTime(nullptr, &_time, &convertedTime); Time converted(convertedTime, localTime); - _stprintf(buffer, _T("%02d:%02d:%02d"), converted.Hours(), converted.Minutes(), converted.Seconds()); + std::snprintf(buffer, sizeof(buffer), _T("%02d:%02d:%02d"), converted.Hours(), converted.Minutes(), converted.Seconds()); } else PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) - _stprintf(buffer, _T("%02d:%02d:%02d"), Hours(), Minutes(), Seconds()); -POP_WARNING() + std::snprintf(buffer, sizeof(buffer), _T("%02d:%02d:%02d"), Hours(), Minutes(), Seconds()); + POP_WARNING() string value(buffer); if( zone != nullptr ) { @@ -843,13 +844,13 @@ POP_WARNING() if (localTime == true) { SYSTEMTIME convertedTime; SystemTimeToTzSpecificLocalTime(nullptr, &_time, &convertedTime); - Time converted(convertedTime, localTime); - _stprintf(buffer, _T("%s, %02d %s %04d %02d:%02d:%02d%s"), converted.WeekDayName(), + Time converted(convertedTime, localTime); + std::snprintf(buffer, sizeof(buffer), _T("%s, %02d %s %04d %02d:%02d:%02d%s"), converted.WeekDayName(), converted.Day(), converted.MonthName(), converted.Year(), converted.Hours(), converted.Minutes(), converted.Seconds(), zone); } else PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) - _stprintf(buffer, _T("%s, %02d %s %04d %02d:%02d:%02d%s"), WeekDayName(), Day(), MonthName(), Year(), + std::snprintf(buffer, sizeof(buffer), _T("%s, %02d %s %04d %02d:%02d:%02d%s"), WeekDayName(), Day(), MonthName(), Year(), Hours(), Minutes(), Seconds(), zone); POP_WARNING() @@ -871,13 +872,13 @@ POP_WARNING() Time converted(convertedTime, localTime); PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) - _stprintf(buffer, _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), converted.Year(), converted.Month(), converted.Day(), converted.Hours(), + std::snprintf(buffer, sizeof(buffer), _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), converted.Year(), converted.Month(), converted.Day(), converted.Hours(), converted.Minutes(), converted.Seconds(), zone); POP_WARNING() } else PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) - _stprintf(buffer, _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), Year(), Month(), Day(), Hours(),Minutes(), Seconds(), zone); -POP_WARNING() + std::snprintf(buffer, sizeof(buffer), _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), Year(), Month(), Day(), Hours(), Minutes(), Seconds(), zone); + POP_WARNING() return (string(buffer)); } @@ -1047,12 +1048,12 @@ POP_WARNING() if (localTime == true) { struct tm localTime{}; localtime_r(&_time.tv_sec, &localTime); - _stprintf(buffer, _T("%s, %02d %s %04d %02d:%02d:%02d%s"), WeekDayName(localTime), + std::snprintf(buffer, sizeof(buffer), _T("%s, %02d %s %04d %02d:%02d:%02d%s"), WeekDayName(localTime), Day(localTime), MonthName(localTime), Year(localTime), Hours(localTime), Minutes(localTime), Seconds(localTime), zone); } else { struct tm utcTime = TMHandle(); - _stprintf(buffer, _T("%s, %02d %s %04d %02d:%02d:%02d%s"), WeekDayName(utcTime), Day(utcTime), MonthName(utcTime), Year(utcTime), Hours(utcTime), + std::snprintf(buffer, sizeof(buffer), _T("%s, %02d %s %04d %02d:%02d:%02d%s"), WeekDayName(utcTime), Day(utcTime), MonthName(utcTime), Year(utcTime), Hours(utcTime), Minutes(utcTime), Seconds(utcTime), zone); } @@ -1070,11 +1071,11 @@ POP_WARNING() if (localTime == true) { struct tm localTime{}; localtime_r(&_time.tv_sec, &localTime); - _stprintf(buffer, _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), Year(localTime), Month(localTime), Day(localTime), Hours(localTime), + std::snprintf(buffer, sizeof(buffer), _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), Year(localTime), Month(localTime), Day(localTime), Hours(localTime), Minutes(localTime), Seconds(localTime), zone); } else { struct tm utcTime = TMHandle(); - _stprintf(buffer, _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), Year(utcTime), Month(utcTime), Day(utcTime), Hours(utcTime),Minutes(utcTime), + std::snprintf(buffer, sizeof(buffer), _T("%04d-%02d-%02dT%02d:%02d:%02d%s"), Year(utcTime), Month(utcTime), Day(utcTime), Hours(utcTime), Minutes(utcTime), Seconds(utcTime), zone); } @@ -1092,10 +1093,10 @@ POP_WARNING() if (localTime == true) { struct tm localTime{}; localtime_r(&_time.tv_sec, &localTime); - _stprintf(buffer, _T("%02d:%02d:%02d"), Hours(localTime), Minutes(localTime), Seconds(localTime)); + std::snprintf(buffer, sizeof(buffer), _T("%02d:%02d:%02d"), Hours(localTime), Minutes(localTime), Seconds(localTime)); } else { struct tm utcTime = TMHandle(); - _stprintf(buffer, _T("%02d:%02d:%02d"), Hours(utcTime), Minutes(utcTime), Seconds(utcTime)); + std::snprintf(buffer, sizeof(buffer), _T("%02d:%02d:%02d"), Hours(utcTime), Minutes(utcTime), Seconds(utcTime)); } string value(buffer); diff --git a/Source/core/Trace.cpp b/Source/core/Trace.cpp index 96ea3a11c..38c4c8d42 100644 --- a/Source/core/Trace.cpp +++ b/Source/core/Trace.cpp @@ -22,6 +22,9 @@ #include "Sync.h" #include "TextFragment.h" #include "Trace.h" +#if defined(__APPLE__) +#include +#endif namespace Thunder { namespace Core { diff --git a/Source/core/Trace.h b/Source/core/Trace.h index 3298e2701..9d278b23f 100644 --- a/Source/core/Trace.h +++ b/Source/core/Trace.h @@ -34,9 +34,8 @@ namespace Thunder { { return (str[i] == '/' || str[i] == '\\') ? i + 1 : (i > 0 ? FileNameOffset(str, i - 1) : 0); } - template - inline constexpr size_t FileNameOffset(T(&str)[1]) + inline constexpr size_t FileNameOffset(T(&str)[1] VARIABLE_IS_NOT_USED) { return 0; } @@ -52,12 +51,14 @@ namespace Thunder { #include #define TRACE_THREAD_ID syscall(SYS_gettid) #else -#include #if INTPTR_MAX == INT64_MAX #define TRACE_THREAD_ID static_cast(::gettid()) #else #define TRACE_THREAD_ID static_cast(::gettid()) #endif +#ifndef __APPLE__ +#include +#endif #endif #endif @@ -75,9 +76,10 @@ namespace Thunder { } while (0) #else #if INTPTR_MAX == INT64_MAX +#include #define TRACE_FORMATTING_IMPL(fmt, ...) \ do { \ - ::fprintf(stderr, "\033[1;32m[%s:%d](%s)" fmt "\033[0m\n", &__FILE__[Thunder::Core::FileNameOffset(__FILE__)], __LINE__, __FUNCTION__, TRACE_PROCESS_ID, TRACE_THREAD_ID, ##__VA_ARGS__); \ + ::fprintf(stderr, "\033[1;32m[%s:%d](%s)" fmt "\033[0m\n", &__FILE__[Thunder::Core::FileNameOffset(__FILE__)], __LINE__, __FUNCTION__, TRACE_PROCESS_ID, TRACE_THREAD_ID, ##__VA_ARGS__); \ fflush(stderr); \ } while (0) #else diff --git a/Source/core/WorkerPool.h b/Source/core/WorkerPool.h index 4f2e4895d..c359bbdff 100644 --- a/Source/core/WorkerPool.h +++ b/Source/core/WorkerPool.h @@ -398,7 +398,7 @@ POP_WARNING() return (result); } - const Metadata& Snapshot() const + const Metadata& Snapshot() const override { _metadata.Slot[0].WorkerId = _timer.ThreadId(); _metadata.Slot[0].Runs = _timer.Pending(); diff --git a/Source/messaging/MessageClient.h b/Source/messaging/MessageClient.h index a6e74c755..79de06cc7 100644 --- a/Source/messaging/MessageClient.h +++ b/Source/messaging/MessageClient.h @@ -59,7 +59,16 @@ namespace Messaging { void RemoveFactory(Core::Messaging::Metadata::type type); private: - using Factories = std::unordered_map; + struct enumHash + { + template + std::size_t operator()(T t) const + { + return static_cast(t); + } + }; + + using Factories = std::unordered_map; using Clients = std::map; mutable Core::CriticalSection _adminLock; diff --git a/Source/plugins/Channel.h b/Source/plugins/Channel.h index be19c4a96..07618c72b 100644 --- a/Source/plugins/Channel.h +++ b/Source/plugins/Channel.h @@ -443,6 +443,7 @@ namespace PluginHost { } private: +PUSH_WARNING(DISABLE_WARNING_INCONSISTENT_MISSING_OVERRIDE) // Handle the WebRequest coming in. virtual void LinkBody(Core::ProxyType& request) = 0; virtual void Received(Core::ProxyType& request) = 0; @@ -465,8 +466,9 @@ namespace PluginHost { // Whenever there is a state change on the link, it is reported here. virtual void StateChange() = 0; +POP_WARNING() - virtual bool IsIdle() const + bool IsIdle() const override { return ((BaseClass::IsWebSocket() == false) || ((_serializer.IsIdle() == true) && (_deserializer.IsIdle() == true))); } diff --git a/Source/plugins/Metadata.h b/Source/plugins/Metadata.h index 7819bc401..fbb313ef3 100644 --- a/Source/plugins/Metadata.h +++ b/Source/plugins/Metadata.h @@ -156,7 +156,7 @@ namespace PluginHost { Server(); ~Server() override = default; - inline void Clear() + inline void Clear() override { ThreadPoolRuns.Clear(); PendingRequests.Clear(); @@ -182,7 +182,7 @@ namespace PluginHost { public: void Add(const PluginHost::ISubSystem::subsystem name, const bool available); - void Clear() + void Clear() override { SubSystems::iterator index(_subSystems.begin()); while (index != _subSystems.end()) { @@ -228,7 +228,8 @@ namespace PluginHost { } ~COMRPC() override = default; - void Clear() { + void Clear() override + { Remote.Clear(); Proxies.Clear(); } diff --git a/Source/websocket/WebLink.h b/Source/websocket/WebLink.h index 354937db6..a60f8b8fa 100644 --- a/Source/websocket/WebLink.h +++ b/Source/websocket/WebLink.h @@ -121,7 +121,7 @@ namespace Web { ~DeserializerImpl() override = default; public: - void Deserialized(typename INBOUND::BaseElement& element) + void Deserialized(typename INBOUND::BaseElement& element) override { ASSERT(&element == static_cast(&(*(_current)))); DEBUG_VARIABLE(element); diff --git a/Source/websocket/WebRequest.h b/Source/websocket/WebRequest.h index 9de9160c8..920090dc4 100644 --- a/Source/websocket/WebRequest.h +++ b/Source/websocket/WebRequest.h @@ -486,17 +486,17 @@ POP_WARNING() } public: - static const TCHAR* GET; - static const TCHAR* HEAD; - static const TCHAR* POST; - static const TCHAR* PUT; - static const TCHAR* DELETE; - static const TCHAR* OPTIONS; - static const TCHAR* TRACE; - static const TCHAR* CONNECT; - static const TCHAR* PATCH; - static const TCHAR* MSEARCH; - static const TCHAR* NOTIFY; + static const TCHAR GET[]; + static const TCHAR HEAD[]; + static const TCHAR POST[]; + static const TCHAR PUT[]; + static const TCHAR DELETE[]; + static const TCHAR OPTIONS[]; + static const TCHAR TRACE[]; + static const TCHAR CONNECT[]; + static const TCHAR PATCH[]; + static const TCHAR MSEARCH[]; + static const TCHAR NOTIFY[]; static const TCHAR* ToString(const type value); static void ToString(const Request& realObject, string& text) @@ -513,7 +513,7 @@ POP_WARNING() ~SerializerImpl() override = default; public: - virtual void Serialized(const Request& /* element */) + void Serialized(const Request& /* element */) override { _ready = true; } @@ -555,18 +555,18 @@ POP_WARNING() public: // The whole request object is deserialised.. - virtual void Deserialized(Web::Request& element VARIABLE_IS_NOT_USED) + void Deserialized(Web::Request& element VARIABLE_IS_NOT_USED) override { } // We need a request object to be able to fill it with info - virtual Web::Request* Element() + Web::Request* Element() override { return (&_destination); } // We reached the body, link a proper body to the response.. - virtual bool LinkBody(Web::Request& request) + bool LinkBody(Web::Request& request) override { return (request.HasBody()); } diff --git a/Source/websocket/WebResponse.h b/Source/websocket/WebResponse.h index 71be15219..9cf0cef51 100644 --- a/Source/websocket/WebResponse.h +++ b/Source/websocket/WebResponse.h @@ -300,7 +300,7 @@ POP_WARNING() ~SerializerImpl() override = default; public: - virtual void Serialized(const Response& /* element */) + void Serialized(const Response& /* element */) override { _ready = true; } @@ -342,18 +342,18 @@ POP_WARNING() public: // The whole request object is deserialised.. - virtual void Deserialized(Web::Response& element VARIABLE_IS_NOT_USED) + void Deserialized(Web::Response& element VARIABLE_IS_NOT_USED) override { } // We need a request object to be able to fill it with info - virtual Web::Response* Element() + Web::Response* Element() override { return (&_destination); } // We reached the body, link a proper body to the response.. - virtual bool LinkBody(Web::Response& request) + bool LinkBody(Web::Response& request) override { return (request.HasBody()); } diff --git a/Source/websocket/WebSerializer.cpp b/Source/websocket/WebSerializer.cpp index 5456f0a4d..9ed9dad0c 100644 --- a/Source/websocket/WebSerializer.cpp +++ b/Source/websocket/WebSerializer.cpp @@ -22,17 +22,17 @@ namespace Thunder { namespace Web { - /* static */ const TCHAR* Request::GET = _T("GET"); - /* static */ const TCHAR* Request::HEAD = _T("HEAD"); - /* static */ const TCHAR* Request::POST = _T("POST"); - /* static */ const TCHAR* Request::PUT = _T("PUT"); - /* static */ const TCHAR* Request::DELETE = _T("DELETE"); - /* static */ const TCHAR* Request::OPTIONS = _T("OPTIONS"); - /* static */ const TCHAR* Request::TRACE = _T("TRACE"); - /* static */ const TCHAR* Request::CONNECT = _T("CONNECT"); - /* static */ const TCHAR* Request::PATCH = _T("PATCH"); - /* static */ const TCHAR* Request::MSEARCH = _T("M-SEARCH"); - /* static */ const TCHAR* Request::NOTIFY = _T("NOTIFY"); + /* static */ const TCHAR Request::GET[] = _T("GET"); + /* static */ const TCHAR Request::HEAD[] = _T("HEAD"); + /* static */ const TCHAR Request::POST[] = _T("POST"); + /* static */ const TCHAR Request::PUT[] = _T("PUT"); + /* static */ const TCHAR Request::DELETE[] = _T("DELETE"); + /* static */ const TCHAR Request::OPTIONS[] = _T("OPTIONS"); + /* static */ const TCHAR Request::TRACE[] = _T("TRACE"); + /* static */ const TCHAR Request::CONNECT[] = _T("CONNECT"); + /* static */ const TCHAR Request::PATCH[] = _T("PATCH"); + /* static */ const TCHAR Request::MSEARCH[] = _T("M-SEARCH"); + /* static */ const TCHAR Request::NOTIFY[] = _T("NOTIFY"); } } diff --git a/Tests/redirect/main.cpp b/Tests/redirect/main.cpp index 69d700e8e..6afbbc235 100644 --- a/Tests/redirect/main.cpp +++ b/Tests/redirect/main.cpp @@ -274,7 +274,7 @@ namespace Test { HANDLE pipeHandle, pipeOutput; TCHAR PipeNameBuffer[MAX_PATH]; - sprintf(PipeNameBuffer, + snprintf(PipeNameBuffer, sizeof(PipeNameBuffer), _T("\\\\.\\Pipe\\ThunderRedirectPipe.%08x.%08x"), Core::ProcessInfo().Id(), newIndex); pipeHandle = CreateNamedPipeA( diff --git a/Tests/unit/CMakeLists.txt b/Tests/unit/CMakeLists.txt index 4a4834b84..2466818d3 100644 --- a/Tests/unit/CMakeLists.txt +++ b/Tests/unit/CMakeLists.txt @@ -23,9 +23,12 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs") -include_directories(${GTEST_INCLUDE_DIR}) +if(NOT APPLE) + include_directories(${GTEST_INCLUDE_DIR}) +endif() SET(BASEPATH "${CMAKE_SOURCE_DIR}") + include_directories(${BASEPATH}/Source) set(CMAKE_CXX_STANDARD 11) diff --git a/Tests/unit/IPTestAdministrator.cpp b/Tests/unit/IPTestAdministrator.cpp index a2c83c50b..a231d62d0 100644 --- a/Tests/unit/IPTestAdministrator.cpp +++ b/Tests/unit/IPTestAdministrator.cpp @@ -201,11 +201,36 @@ void IPTestAdministrator::TimedLock(pthread_mutex_t * mutex, const std::string & { timespec timeSpec; FillTimeOut(timeSpec); +#ifdef __APPLE__ + int result; + do { + result = pthread_mutex_trylock(mutex); + if (result == EBUSY) { + int wait = -1; + timespec ts; + ts.tv_sec = 1000; + if (timeSpec.tv_sec > 1000) { + timeSpec.tv_sec -= ts.tv_sec; + } else if (timeSpec.tv_sec != -1) { + ts.tv_sec = timeSpec.tv_sec; + timeSpec.tv_sec = 0; + } + + while (wait == -1) { + wait = nanosleep(&ts, &ts); + } + } else { + break; + } + } while (result != 0); + +#else int result = pthread_mutex_timedlock(mutex, &timeSpec); if (result == ETIMEDOUT) { fprintf(stderr, "While locking mutex, time out expired for \"%s\" in %s.\n", str.c_str(), GetProcessName()); abort(); } +#endif } void IPTestAdministrator::TimedWait(pthread_cond_t * cond, pthread_mutex_t * mutex, const std::string & str) { diff --git a/Tests/unit/core/CMakeLists.txt b/Tests/unit/core/CMakeLists.txt index 34e548504..23c64c46c 100644 --- a/Tests/unit/core/CMakeLists.txt +++ b/Tests/unit/core/CMakeLists.txt @@ -21,7 +21,7 @@ set(TEST_RUNNER_NAME "Thunder_test_core") add_executable(${TEST_RUNNER_NAME} ../IPTestAdministrator.cpp - test_cyclicbuffer.cpp + #test_cyclicbuffer.cpp test_databuffer.cpp test_dataelement.cpp test_dataelementfile.cpp @@ -56,7 +56,7 @@ add_executable(${TEST_RUNNER_NAME} test_rectangle.cpp test_rpc.cpp test_semaphore.cpp - test_sharedbuffer.cpp + #test_sharedbuffer.cpp test_singleton.cpp test_socketstreamjson.cpp test_socketstreamtext.cpp @@ -72,7 +72,7 @@ add_executable(${TEST_RUNNER_NAME} test_time.cpp test_timer.cpp test_tristate.cpp - # test_valuerecorder.cpp + #test_valuerecorder.cpp test_weblinkjson.cpp test_weblinktext.cpp test_websocketjson.cpp @@ -104,8 +104,14 @@ target_compile_definitions(${TEST_RUNNER_NAME} PRIVATE BUILD_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" ) -target_link_libraries(${TEST_RUNNER_NAME} - ${GTEST_BOTH_LIBRARIES} +if (APPLE) + set(GTEST_LIBRARY GTest::gtest GTest::gtest_main) +else() + set(GTEST_LIBRARY "${GTEST_BOTH_LIBRARIES}") +endif() + +target_link_libraries(${TEST_RUNNER_NAME} + ${GTEST_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${NAMESPACE}Core::${NAMESPACE}Core ${NAMESPACE}COM::${NAMESPACE}COM diff --git a/Tests/unit/core/test_cyclicbuffer.cpp b/Tests/unit/core/test_cyclicbuffer.cpp index bda7fb48d..50271970e 100644 --- a/Tests/unit/core/test_cyclicbuffer.cpp +++ b/Tests/unit/core/test_cyclicbuffer.cpp @@ -27,6 +27,10 @@ #include "../IPTestAdministrator.h" +#ifdef __APPLE__ +#include +#endif + namespace Thunder { namespace Tests { namespace Core { diff --git a/Tests/unit/core/test_hash.cpp b/Tests/unit/core/test_hash.cpp index fd87cfb7d..5ce312ca2 100644 --- a/Tests/unit/core/test_hash.cpp +++ b/Tests/unit/core/test_hash.cpp @@ -89,7 +89,7 @@ namespace Core { for (const unsigned char *ptr = buffer; ptr < buffer + length; ++ptr) { char buf[3]; - sprintf(buf, "%02x", (*ptr)&0xff); + snprintf(buf, sizeof(buf), "%02x", (*ptr)&0xff); hash += buf; } return hash; diff --git a/Tests/unit/core/test_jsonparser.cpp b/Tests/unit/core/test_jsonparser.cpp index 678ee6bdc..68c72f5f9 100644 --- a/Tests/unit/core/test_jsonparser.cpp +++ b/Tests/unit/core/test_jsonparser.cpp @@ -2020,7 +2020,7 @@ namespace Core { ~SmallTest() override = default; public: - void Clear() + void Clear() override { ::Thunder::Core::JSON::Container::Clear(); } @@ -2049,7 +2049,7 @@ namespace Core { ~SmallTest2() override = default; public: - void Clear() + void Clear() override { ::Thunder::Core::JSON::Container::Clear(); } @@ -2152,7 +2152,7 @@ namespace Core { ~CommandRequest() override = default; - void Clear() + void Clear() override { ::Thunder::Core::JSON::Container::Clear(); } diff --git a/Tests/unit/core/test_library.cpp b/Tests/unit/core/test_library.cpp index f556b2522..04302debc 100644 --- a/Tests/unit/core/test_library.cpp +++ b/Tests/unit/core/test_library.cpp @@ -44,7 +44,9 @@ namespace Core { ::Thunder::Core::Library LibObj1(file.c_str()); EXPECT_TRUE(LibObj1.Error().empty()); +#ifndef __APPLE__ LibObj1.LoadFunction(function); +#endif EXPECT_TRUE(LibObj1.IsLoaded()); EXPECT_TRUE(LibObj1.Error().empty()); diff --git a/Tests/unit/core/test_numbertype.cpp b/Tests/unit/core/test_numbertype.cpp index 27fe4e61c..ce61393b0 100644 --- a/Tests/unit/core/test_numbertype.cpp +++ b/Tests/unit/core/test_numbertype.cpp @@ -40,10 +40,6 @@ namespace Core { TEST(Core_NumberType, generic) { - ::Thunder::Core::NumberType numbertype; - string buffer = "/Service/testing/numbertype"; - ::Thunder::Core::NumberType<::Thunder::Core::TextFragment> typetextfragment(::Thunder::Core::TextFragment(string(buffer))); - string valdata = "90"; ::Thunder::Core::NumberType val1 = Tester<::Thunder::Core::NumberType>(valdata); ::Thunder::Core::NumberType val2 = Tester<::Thunder::Core::NumberType>(valdata); diff --git a/Tests/unit/core/test_rpc.cpp b/Tests/unit/core/test_rpc.cpp index ffe3c028f..c2fdf2d9e 100644 --- a/Tests/unit/core/test_rpc.cpp +++ b/Tests/unit/core/test_rpc.cpp @@ -49,17 +49,17 @@ namespace Exchange { { } - uint32_t GetValue() + uint32_t GetValue() override { return m_value; } - void Add(uint32_t value) + void Add(uint32_t value) override { m_value += value; } - uint32_t GetPid() + uint32_t GetPid() override { return getpid(); } @@ -251,6 +251,7 @@ namespace Exchange { TEST(Core_RPC, adder) { +#ifndef __APPLE__ std::string connector{"/tmp/wperpc01"}; auto lambdaFunc = [connector](IPTestAdministrator & testAdmin) { ::Thunder::Core::NodeId remoteNode(connector.c_str()); @@ -302,6 +303,7 @@ namespace Exchange { testAdmin.Sync("done testing"); ::Thunder::Core::Singleton::Dispose(); +#endif } } // Core diff --git a/Tests/unit/core/test_singleton.cpp b/Tests/unit/core/test_singleton.cpp index cf65be489..1b1c6a046 100644 --- a/Tests/unit/core/test_singleton.cpp +++ b/Tests/unit/core/test_singleton.cpp @@ -63,12 +63,14 @@ namespace Core { static SingletonTypeOne& object1 = ::Thunder::Core::SingletonType::Instance(); static SingletonTypeOne& object_sample = ::Thunder::Core::SingletonType::Instance(); EXPECT_EQ(&object1,&object_sample); +#ifndef __APPLE__ // These are already marked as deprecated in core/Singleton.h, so commenting to avoid warning static SingletonTypeTwo& object2 = ::Thunder::Core::SingletonType::Instance("SingletonTypeTwo"); static SingletonTypeThree& object3 = ::Thunder::Core::SingletonType::Instance("SingletonTypeThree","SingletonTypeThree"); ::Thunder::Core::SingletonType* x = (::Thunder::Core::SingletonType*)&object2; EXPECT_STREQ(x->ImplementationName().c_str(),"SingletonTypeTwo"); ::Thunder::Core::SingletonType* y = (::Thunder::Core::SingletonType*)&object3; EXPECT_STREQ(y->ImplementationName().c_str(),"SingletonTypeThree"); +#endif ::Thunder::Core::Singleton::Dispose(); } diff --git a/Tests/unit/core/test_systeminfo.cpp b/Tests/unit/core/test_systeminfo.cpp index 490454907..28a627f68 100644 --- a/Tests/unit/core/test_systeminfo.cpp +++ b/Tests/unit/core/test_systeminfo.cpp @@ -21,7 +21,9 @@ #include #include #include +#ifndef __APPLE__ #include +#endif #include @@ -537,10 +539,12 @@ namespace Core { uint64_t* cpuLoadAvg = ::Thunder::Core::SystemInfo::Instance().GetCpuLoadAvg(); double loadFromThunder[3]; +#ifndef __APPLE__ // Fixed point arithmetic EXPECT_DOUBLE_EQ(loadFromSystem[0], cpuLoadAvg[0] / (1 << SI_LOAD_SHIFT)); EXPECT_DOUBLE_EQ(loadFromSystem[1], cpuLoadAvg[1] / (1 << SI_LOAD_SHIFT)); EXPECT_DOUBLE_EQ(loadFromSystem[2], cpuLoadAvg[2] / (1 << SI_LOAD_SHIFT)); +#endif } } #endif diff --git a/Tests/unit/core/test_workerpool.cpp b/Tests/unit/core/test_workerpool.cpp index 909e0798d..13449e4cf 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(pthread_self())); + sprintf(id, "%x", static_cast<::ThreadId>(pthread_self())); for (uint8_t index = 0; index < _threadsCount + 2; index++) { char workerId[MaxSize]; - sprintf(workerId, "%x", static_cast(::Thunder::Core::IWorkerPool::Instance().Id(index))); + sprintf(workerId, "%x", static_cast<::ThreadId>(::Thunder::Core::IWorkerPool::Instance().Id(index))); if (strcpy(workerId, id)) { isPoolId = true; @@ -1444,4 +1444,4 @@ namespace Core { } // Core } // Tests -} // Thunder \ No newline at end of file +} // Thunder diff --git a/cmake/common/CompileSettingsDebug.cmake b/cmake/common/CompileSettingsDebug.cmake index c1eb3ddc7..7b10abeca 100644 --- a/cmake/common/CompileSettingsDebug.cmake +++ b/cmake/common/CompileSettingsDebug.cmake @@ -29,12 +29,12 @@ include(CMakePackageConfigHelpers) # Build type specific options # if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR ${CMAKE_COMPILER_IS_GNUCXX} ) + if(CMAKE_CXX_COMPILER_ID MATCHES "^(Apple)?Clang$") target_compile_options(CompileSettingsDebug INTERFACE -O0 -g) endif() elseif("${CMAKE_BUILD_TYPE}" STREQUAL "DebugOptimized") - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR ${CMAKE_COMPILER_IS_GNUCXX} ) + if(CMAKE_CXX_COMPILER_ID MATCHES "^(Apple)?Clang$" OR ${CMAKE_COMPILER_IS_GNUCXX}) target_compile_options(CompileSettingsDebug INTERFACE -O2 -g) endif() diff --git a/cmake/project.cmake.in b/cmake/project.cmake.in index f567846da..e0e636b90 100644 --- a/cmake/project.cmake.in +++ b/cmake/project.cmake.in @@ -118,8 +118,8 @@ endif() if(ENABLE_STRICT_COMPILER_SETTINGS) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - message(FATAL_ERROR "Compiling with Clang") - set(CMAKE_STRICT_COMPILER_SETTINGS "-Weverything -Wextra -Werror=return-type -Werror=array-bounds") + message(STATUS "Compiling with Clang") + set(CMAKE_STRICT_COMPILER_SETTINGS "-Wall -Wextra -Werror=return-type -Werror=array-bounds") set(CMAKE_STRICT_CXX_COMPILER_SETTINGS "${CMAKE_STRICT_COMPILER_SETTINGS} -Wnon-virtual-dtor") elseif(${CMAKE_COMPILER_IS_GNUCXX}) message(STATUS "Compiling with GCC") From 7f048dae02c97935809ad39c658653a51b2c8603 Mon Sep 17 00:00:00 2001 From: MFransen69 <39826971+MFransen69@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:52:15 +0200 Subject: [PATCH 3/6] [Core] Fix windows build (#1684) --- Source/core/SocketPort.cpp | 4 ++-- Source/core/Thread.cpp | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Source/core/SocketPort.cpp b/Source/core/SocketPort.cpp index 88cd6f114..a8ae1e55d 100644 --- a/Source/core/SocketPort.cpp +++ b/Source/core/SocketPort.cpp @@ -63,14 +63,14 @@ #define __ERROR_CONNRESET__ WSAECONNRESET #define __ERROR_NETWORK_UNREACHABLE__ WSAENETUNREACH PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) -#else +#endif #ifdef __APPLE__ #define IPV6_PACKAGE_TYPE IPV6_RECVPKTINFO #else #define IPV6_PACKAGE_TYPE IPV6_PKTINFO #endif -#endif + namespace Thunder { namespace Core { diff --git a/Source/core/Thread.cpp b/Source/core/Thread.cpp index 56a659661..690a43af7 100644 --- a/Source/core/Thread.cpp +++ b/Source/core/Thread.cpp @@ -74,10 +74,6 @@ namespace Core { // then it is up to us. if (m_hThreadInstance == nullptr) #endif - std::string convertedName; - if (threadName != nullptr) { - Core::ToString(threadName, convertedName); - } #ifdef __POSIX__ int err; @@ -93,7 +89,6 @@ namespace Core { ASSERT(err == 0); } - m_threadName = convertedName; // If there is no thread, the "new" thread can also not free the destructor, // then it is up to us. @@ -105,10 +100,16 @@ namespace Core { m_sigExit.SetEvent(); } + std::string convertedName; + if (threadName != nullptr) { + Core::ToString(threadName, convertedName); + } + #ifdef __POSIX__ err = pthread_attr_destroy(&attr); ASSERT(err == 0); m_ThreadId = m_hThreadInstance; + m_threadName = convertedName; #else if (convertedName.empty() != true) { ThreadName(convertedName.c_str()); From 59bdf3da67e564b5f21803bf28dd9174c61888f0 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Wed, 3 Jul 2024 16:18:22 +0200 Subject: [PATCH 4/6] Development/portable build (#1681) * cmake: use dynamic include folder * cmake: find templates relative to the helper functions file * cmake: find templates relative to the header only install function file * cmake: local source path should not be dynamic * cmake: add component definitions * cmake: move to dynamic cmake paths * docs: remove note * docs: add missing package * docs: cleanup double thunder --- README.md | 2 +- Source/core/CMakeLists.txt | 2 +- Source/cryptalgo/CMakeLists.txt | 2 +- Source/extensions/localtracer/CMakeLists.txt | 2 +- .../privilegedrequest/CMakeLists.txt | 3 +- .../processcontainers/CMakeLists.txt | 2 +- .../warningreporting/CMakeLists.txt | 2 +- Source/messaging/CMakeLists.txt | 6 +-- Source/plugins/CMakeLists.txt | 2 +- Source/websocket/CMakeLists.txt | 2 +- cmake/common/CmakeHelperFunctions.cmake | 39 ++++++++++++++----- cmake/common/HeaderOnlyInstall.cmake | 39 ++++++++++++++----- docs/introduction/build_linux.md | 2 +- docs/introduction/intro.md | 2 - 14 files changed, 73 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 49ff9dbae..b04266727 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ![Linux Build](https://github.com/rdkcentral/Thunder/actions/workflows/Build%20Thunder%20on%20Linux.yml/badge.svg) ![Windows Build](https://github.com/rdkcentral/Thunder/actions/workflows/Build%20Thunder%20on%20Windows.yml/badge.svg) ![Unit Test](https://github.com/rdkcentral/Thunder/actions/workflows/Test%20Thunder.yml/badge.svg) -Thunder (also known as Thunder) is an open-source plugin-based device abstraction layer, where business functionality can be implemented as plugins and applications can query and control those plugins. Using Thunder provides a consistent interface-driven development model for both plugins and client applications, with an RPC engine that is suited to both web-based and native apps. +Thunder is an open-source plugin-based device abstraction layer, where business functionality can be implemented as plugins and applications can query and control those plugins. Using Thunder provides a consistent interface-driven development model for both plugins and client applications, with an RPC engine that is suited to both web-based and native apps. Designed from the ground up for embedded platforms and written in C++11, Thunder can be run on even the most low-power of devices (including ARM and MIPS-based platforms). diff --git a/Source/core/CMakeLists.txt b/Source/core/CMakeLists.txt index bc3380d76..a408e5adf 100644 --- a/Source/core/CMakeLists.txt +++ b/Source/core/CMakeLists.txt @@ -252,7 +252,7 @@ target_include_directories( ${TARGET} PUBLIC $ $ #core.h - $) + $) if(LIBRT_FOUND) target_link_libraries(${TARGET} diff --git a/Source/cryptalgo/CMakeLists.txt b/Source/cryptalgo/CMakeLists.txt index eb42f04f6..2ca25af8c 100644 --- a/Source/cryptalgo/CMakeLists.txt +++ b/Source/cryptalgo/CMakeLists.txt @@ -81,7 +81,7 @@ target_include_directories( ${TARGET} PUBLIC $ $ - $ + $ ) install( diff --git a/Source/extensions/localtracer/CMakeLists.txt b/Source/extensions/localtracer/CMakeLists.txt index a978c7e84..d51548ac5 100644 --- a/Source/extensions/localtracer/CMakeLists.txt +++ b/Source/extensions/localtracer/CMakeLists.txt @@ -25,7 +25,7 @@ target_compile_features(${MODULE_NAME} INTERFACE cxx_std_11) install(TARGETS ${MODULE_NAME} EXPORT ${MODULE_NAME}Targets) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/localtracer/localtracer.h +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/localtracer/localtracer.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/localtracer COMPONENT ${NAMESPACE}_Development) include(HeaderOnlyInstall) diff --git a/Source/extensions/privilegedrequest/CMakeLists.txt b/Source/extensions/privilegedrequest/CMakeLists.txt index a64eb7e6d..21369ce91 100644 --- a/Source/extensions/privilegedrequest/CMakeLists.txt +++ b/Source/extensions/privilegedrequest/CMakeLists.txt @@ -39,8 +39,7 @@ target_compile_features(${MODULE_NAME} INTERFACE cxx_std_11) install(TARGETS ${MODULE_NAME} EXPORT ${MODULE_NAME}Targets) -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_INSTALL_INCLUDEDIR}/privilegedrequest/PrivilegedRequest.h +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/privilegedrequest/PrivilegedRequest.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/privilegedrequest COMPONENT ${NAMESPACE}_Development) include(HeaderOnlyInstall) diff --git a/Source/extensions/processcontainers/CMakeLists.txt b/Source/extensions/processcontainers/CMakeLists.txt index 996b13834..b25939a34 100644 --- a/Source/extensions/processcontainers/CMakeLists.txt +++ b/Source/extensions/processcontainers/CMakeLists.txt @@ -85,7 +85,7 @@ target_include_directories( ${TARGET} PUBLIC $ $ - $ + $ ) if (PROCESSCONTAINERS_LXC) diff --git a/Source/extensions/warningreporting/CMakeLists.txt b/Source/extensions/warningreporting/CMakeLists.txt index 4e751ac72..c7f9d5f36 100644 --- a/Source/extensions/warningreporting/CMakeLists.txt +++ b/Source/extensions/warningreporting/CMakeLists.txt @@ -57,7 +57,7 @@ target_include_directories( ${TARGET} PUBLIC $ $ - $ + $ ) install( diff --git a/Source/messaging/CMakeLists.txt b/Source/messaging/CMakeLists.txt index d8125bc44..e190eda82 100644 --- a/Source/messaging/CMakeLists.txt +++ b/Source/messaging/CMakeLists.txt @@ -72,7 +72,7 @@ target_include_directories( ${TARGET} PUBLIC $ $ - $ + $ ) install( @@ -95,8 +95,8 @@ include(CreateLink) InstallCompatibleCMakeConfig( TARGET ${TARGET} LEGACY_TARGET ${NAMESPACE}Tracing - LEGACY_INCLUDE_DIR "include/${NAMESPACE}" - LEGACY_PUBLIC_HEADER_LOCATION "include/${NAMESPACE}/tracing") + LEGACY_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}" + LEGACY_PUBLIC_HEADER_LOCATION "${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/tracing") createlink( LINK ${CMAKE_CURRENT_BINARY_DIR}/tracing.h diff --git a/Source/plugins/CMakeLists.txt b/Source/plugins/CMakeLists.txt index d97383671..a018bbc2f 100644 --- a/Source/plugins/CMakeLists.txt +++ b/Source/plugins/CMakeLists.txt @@ -111,7 +111,7 @@ target_include_directories( ${TARGET} PUBLIC $ $ - $ + $ ) target_include_directories( ${TARGET_PROXYSTUBS} diff --git a/Source/websocket/CMakeLists.txt b/Source/websocket/CMakeLists.txt index 2f39a23b1..2a571b06e 100644 --- a/Source/websocket/CMakeLists.txt +++ b/Source/websocket/CMakeLists.txt @@ -71,7 +71,7 @@ target_include_directories( ${TARGET} PUBLIC $ $ - $ + $ ) install( diff --git a/cmake/common/CmakeHelperFunctions.cmake b/cmake/common/CmakeHelperFunctions.cmake index 78fd3b245..c071e235d 100644 --- a/cmake/common/CmakeHelperFunctions.cmake +++ b/cmake/common/CmakeHelperFunctions.cmake @@ -18,6 +18,8 @@ include(CMakePackageConfigHelpers) include(GNUInstallDirs) +set(TEMPLATES_LOCATION_RELATIVE_FROM_ME "${CMAKE_CURRENT_LIST_DIR}/../templates/" CACHE INTERNAL "relative location to the templates from this file") + macro(add_element list element) list(APPEND ${list} ${element}) endmacro() @@ -317,7 +319,11 @@ function(InstallCMakeConfig) if("${Argument_TEMPLATE}" STREQUAL "") find_file( _config_template NAMES "defaultConfig.cmake.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" NO_DEFAULT_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH @@ -327,7 +333,11 @@ function(InstallCMakeConfig) find_file(_config_template NAMES "defaultConfig.cmake.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" ) + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" ) if(NOT EXISTS "${_config_template}") message(SEND_ERROR "Config file generation failed, template '${_config_template}' not found") @@ -457,12 +467,14 @@ function(InstallCMakeConfig) install(EXPORT "${_target}Targets" FILE "${_name}Targets.cmake" NAMESPACE "${_name}::" - DESTINATION "${_install_path}/${_name}") + DESTINATION "${_install_path}/${_name}" + COMPONENT ${NAMESPACE}_Development) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${_name}ConfigVersion.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${_name}Config.cmake" - DESTINATION "${_install_path}/${_name}") + DESTINATION "${_install_path}/${_name}" + COMPONENT ${NAMESPACE}_Development) endforeach() endfunction(InstallCMakeConfig) @@ -480,7 +492,11 @@ function(InstallPackageConfig) if("${Argument_TEMPLATE}" STREQUAL "") find_file( _pc_template NAMES "default.pc.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" NO_DEFAULT_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH @@ -490,7 +506,11 @@ function(InstallPackageConfig) find_file(_pc_template NAMES "default.pc.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates") + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates") if(NOT EXISTS "${_pc_template}") message(SEND_ERROR "PC file generation failed, template '${_pc_template}' not found") @@ -615,7 +635,8 @@ function(InstallPackageConfig) @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${_pc_filename}" - DESTINATION "${_install_path}") + DESTINATION "${_install_path}" + COMPONENT ${NAMESPACE}_Development) endforeach() endfunction(InstallPackageConfig) @@ -638,11 +659,11 @@ function(InstallFindModule) else() file(GLOB_RECURSE extra_files "${DIRECTORY}/*.cmake") endif(Argument_RECURSE) - install(FILES "${extra_files}" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/modules) + install(FILES "${extra_files}" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/modules COMPONENT ${NAMESPACE}_Development) endif() if (Argument_FILES) - install(FILES "${Argument_FILES}" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/modules) + install(FILES "${Argument_FILES}" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/modules COMPONENT ${NAMESPACE}_Development) endif() endfunction(InstallFindModule) diff --git a/cmake/common/HeaderOnlyInstall.cmake b/cmake/common/HeaderOnlyInstall.cmake index e2f569682..53e0f8498 100644 --- a/cmake/common/HeaderOnlyInstall.cmake +++ b/cmake/common/HeaderOnlyInstall.cmake @@ -1,3 +1,5 @@ +set(TEMPLATES_LOCATION_RELATIVE_FROM_ME "${CMAKE_CURRENT_LIST_DIR}/../templates/" CACHE INTERNAL "relative location to the templates from this file") + function(HeaderOnlyInstallCMakeConfig) set(optionsArgs NO_SKIP_INTERFACE_LIBRARIES, TREAT_AS_NORMAL) set(oneValueArgs LOCATION TEMPLATE TARGET) @@ -9,7 +11,7 @@ function(HeaderOnlyInstallCMakeConfig) message(FATAL_ERROR "Unknown keywords given to HeaderOnlyInstallCMakeConfig(): \"${Argument_UNPARSED_ARGUMENTS}\"") endif() - set(_install_path "lib/cmake") # default path + set(_install_path "${CMAKE_INSTALL_LIBDIR}/cmake") # default path set(TARGET ${Argument_TARGET}) set(NAME ${Argument_NAME}) @@ -21,7 +23,11 @@ function(HeaderOnlyInstallCMakeConfig) if("${Argument_TEMPLATE}" STREQUAL "") find_file( _config_template NAMES "defaultConfig.cmake.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" NO_DEFAULT_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH @@ -31,7 +37,11 @@ function(HeaderOnlyInstallCMakeConfig) find_file(_config_template NAMES "defaultConfig.cmake.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" ) + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" ) if(NOT EXISTS "${_config_template}") message(SEND_ERROR "Config file generation failed, template '${_config_template}' not found") @@ -151,12 +161,14 @@ function(HeaderOnlyInstallCMakeConfig) EXPORT "${TARGET}Targets" FILE "${_name}Targets.cmake" NAMESPACE "${_name}::" - DESTINATION "${_install_path}/${_name}") + DESTINATION "${_install_path}/${_name}" + COMPONENT ${NAMESPACE}_Development) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${_name}ConfigVersion.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${_name}Config.cmake" - DESTINATION "${_install_path}/${_name}") + DESTINATION "${_install_path}/${_name}" + COMPONENT ${NAMESPACE}_Development) endfunction(HeaderOnlyInstallCMakeConfig) @@ -174,7 +186,11 @@ function(HeaderOnlyInstallPackageConfig) if("${Argument_TEMPLATE}" STREQUAL "") find_file( _pc_template NAMES "default.pc.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" NO_DEFAULT_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH @@ -184,7 +200,11 @@ function(HeaderOnlyInstallPackageConfig) find_file(_pc_template NAMES "default.pc.in" - PATHS "${PROJECT_SOURCE_DIR}/cmake/templates" "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates") + PATHS + "${TEMPLATES_LOCATION_RELATIVE_FROM_ME}" + "${PROJECT_SOURCE_DIR}/cmake/templates" + "${CMAKE_SYSROOT}/usr/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates" + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/${NAMESPACE}/templates") if(NOT EXISTS "${_pc_template}") message(SEND_ERROR "PC file generation failed, template '${_pc_template}' not found") @@ -229,7 +249,7 @@ function(HeaderOnlyInstallPackageConfig) endif() # Default path on UNIX, if you want Windows or Apple support add the path here. ;-) - set(_install_path "lib/pkgconfig") + set(_install_path "${CMAKE_INSTALL_LIBDIR}/pkgconfig") if (${Argument_OUTPUT_NAME}) set(_pc_filename ${Argument_OUTPUT_NAME}) @@ -301,5 +321,6 @@ function(HeaderOnlyInstallPackageConfig) @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${_pc_filename}" - DESTINATION "${_install_path}") + DESTINATION "${_install_path}" + COMPONENT ${NAMESPACE}_Development) endfunction(HeaderOnlyInstallPackageConfig) diff --git a/docs/introduction/build_linux.md b/docs/introduction/build_linux.md index c8ccb5373..d677a310f 100644 --- a/docs/introduction/build_linux.md +++ b/docs/introduction/build_linux.md @@ -16,7 +16,7 @@ The following instructions will use the `CMAKE_INSTALL_PREFIX` option to install These instructions are based on Ubuntu 22.04 - you may need to change this for your distros package manager ``` -sudo apt install build-essential cmake ninja-build libusb-1.0-0-dev zlib1g-dev libssl-dev +sudo apt install build-essential pkg-config cmake ninja-build libusb-1.0-0-dev zlib1g-dev libssl-dev ``` Thunder also uses Python 3 for code and documentation generation scripts. Ensure you have at least **Python 3.5** installed and install the [**jsonref**](https://pypi.org/project/jsonref/) library with pip: diff --git a/docs/introduction/intro.md b/docs/introduction/intro.md index 3e2ed0d8e..d343b1429 100644 --- a/docs/introduction/intro.md +++ b/docs/introduction/intro.md @@ -1,6 +1,4 @@ # What is Thunder? -!!! note - The terms "**Thunder**" and "**Thunder**" may be used interchangeably throughout this documentation. The project was originally known as Thunder (since it was developed by the Web Platform for Embedded, or WPE, team). The name was changed to Thunder when it was incorporated into RDK, but the code still uses the name Thunder internally. ## Introduction From f971bb864cea6ab256f9d9801bb2f40d64923521 Mon Sep 17 00:00:00 2001 From: MFransen69 <39826971+MFransen69@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:05:35 +0200 Subject: [PATCH 5/6] [doc] update @text documentation (#1687) --- docs/plugin/interfaces/tags.md | 40 +++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/plugin/interfaces/tags.md b/docs/plugin/interfaces/tags.md index 37268353b..f58701a8e 100644 --- a/docs/plugin/interfaces/tags.md +++ b/docs/plugin/interfaces/tags.md @@ -225,7 +225,7 @@ In [IPerformance.h](https://github.com/rdkcentral/ThunderInterfaces/blob/5fa166b |[@index](#index)|Marks an index parameter to a property or notification | | No| Yes|Method paramter| |[@opaque](#opaque)| Indicates that a string parameter is an opaque JSON object | | No | Yes |Method parameter| |[@alt](#alt)| Provides an alternative name a method can by called by | | No | Yes |Method| -|[@text](#text)| Renames identifier METHOD, PARAM, POD MEMBER, enum | | No | Yes |enum, Method paramters, Method names, PoD member| +|[@text](#text)| Renames identifier Method, Parameter, PoD Member, Enum, Interface | | No | Yes |Enum, Method parameter, Method name, PoD member, Interface | #### @json This tag helps to generate JSON-RPC files for the given Class/Struct/enum. @@ -403,18 +403,48 @@ Provide an alternative name for the method. JSON-RPC methods will be generated f
#### @text -This tag is applicable to enums, function names and function parameters. +This tag is applicable to enums, method names, method parameters, PoD members and whole interfaces. -* When used with enum, it will associate the enum values to the given text in the JSON code. -* When used in function names, it will replace the actual function name with the text that is given. -* When used in function parameter, it will replace the parameter name with the text that is given in the tag. +* When used for an enum value, it will associate the enum values to the given text in the JSON code while keeping the case of the given text as is. +* When used for a method name, it will replace the actual method name with the text that is given in the tag while keeping the case of the text as is. +* When used for a method parameter, it will replace the parameter name with the text that is given in the tag while keeping the case of the text as is. +* When used for a PoD member, it will replace the PoD member name with the text that is given in the tag while keeping the case of the text as is. Please note that the tag must be placed before the ';' following the PoD member name (see the examples below). +* When used for a whole interface it must be used in the form '@text:keep'. It will in this case make the JSON generator use the name of the above items in JSON code exactly as specified in the interface, including the case of the text. Please note that of course the interface designer is responsible for making the interface compliant and consistent with the interface guideliness in use (even more perhaps then with the other uses of @text as now the whole interface is influenced). Please see an example on how to apply this form of @text below in the examples. ##### Example +
[IBrowser.h](https://github.com/rdkcentral/ThunderInterfaces/blob/5fa166bd17c6b910696c6113c5520141bcdea07b/interfaces/IBrowser.h#L61) uses this tag for enum. The generated code for this header will map the text for these enums as allowed and not as Allowed, blocked and not as Blocked. Without these tags the string equivalent of the enums will be first letter caps followed by all small. This tag has changed it to all small. + +
+ +[IDolby.h](https://github.com/rdkcentral/ThunderInterfaces/blob/ac6cd5e8fe6b1735d811ec85633d145e1c1d4945/interfaces/IDolby.h#L62) uses this tag for method names. The generated code for this header will map the text for this method to the name 'soundmodechanged'. As can be seen @text can be combined with @alt if needed so in this case in the JSON-RPC interface this method can be called with both 'soundmodechanged' as well as 'dolby_audiomodechanged' + + +
+ +In this example the names for PoD member 'One' will be mapped to 'First' and 'Two' will be mapped to 'Second' in the generated code. So in the JSON-RPC interface the JSON container names will be 'First' and 'Second' for these PoD members. +```cpp hl_lines="1" + struct EXTERNAL Example { + uint32_t One /* @text First */; + uint32_t Two /* @text Second */; + }; +``` + +
+ +In this example now for all enums, method names, method parameters and PoD member names the exact name as in the IExample interface will be used in the JSON generated code. + +```cpp hl_lines="1" + /* @json 1.0.0 @text:keep */ + struct EXTERNAL IExample : virtual public Core::IUnknown { +``` + + + ### JSON-RPC Documentation Related Tags From 010eefb560f6c9bdfd1be6098b463e8f7f4495a5 Mon Sep 17 00:00:00 2001 From: MFransen69 <39826971+MFransen69@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:18:22 +0200 Subject: [PATCH 6/6] [plugins] fix very small issue in IShell (#1686) --- Source/plugins/IShell.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/plugins/IShell.h b/Source/plugins/IShell.h index de0e09f9a..40958f3ec 100644 --- a/Source/plugins/IShell.h +++ b/Source/plugins/IShell.h @@ -301,7 +301,7 @@ namespace PluginHost { } inline Core::hresult Unregister(const RPC::IRemoteConnection::INotification* sink) { - Core::hresult result; + Core::hresult result = Core::ERROR_NONE; ASSERT(sink != nullptr);