From 3a82e15301291fdeb4dd382088a5ca2f968ae55c Mon Sep 17 00:00:00 2001 From: Pierre Wielders Date: Mon, 11 Nov 2024 10:44:06 +0100 Subject: [PATCH] =?UTF-8?q?[METADATA]=20Expose=20all=20COMRPC=20metadata?= =?UTF-8?q?=20like=20Channels=20and=20Proxies=20(also=E2=80=A6=20(#1775)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [METADATA] Expose all COMRPC metadata like Channels and Proxies (also the private channels) * Update IController.h * Update IUnknown.cpp * Update test_rpc.cpp * Update IUnknown.cpp Thank you Coverity! I like tools that add value :-) * Update IUnknown.cpp * [FIXES] After testing on windows :-) * Update IShell.h * Update PluginHost.cpp * Update test_rpc.cpp --------- Co-authored-by: MFransen69 <39826971+MFransen69@users.noreply.github.com> Co-authored-by: Volkan Aslan --- Source/Thunder/Controller.cpp | 11 ++++- Source/Thunder/Controller.h | 2 +- Source/Thunder/ExampleConfigWindows.json | 30 +++++------- Source/Thunder/PluginHost.cpp | 4 +- Source/Thunder/PluginServer.h | 32 ++++++++++--- Source/com/Administrator.cpp | 44 ++++++++++++------ Source/com/Administrator.h | 22 ++++++--- Source/com/Communicator.cpp | 17 ++++--- Source/com/Communicator.h | 59 ++++++++++++++++++++---- Source/com/IUnknown.cpp | 15 ++---- Source/com/IUnknown.h | 14 +++--- Source/core/IPCConnector.h | 22 +++++++++ Source/core/SocketPort.h | 8 ++-- Source/core/SocketServer.h | 2 +- Source/plugins/IController.h | 8 ++-- Source/plugins/IShell.h | 14 +++--- Source/plugins/plugins.vcxproj | 6 ++- Tests/unit/core/test_rpc.cpp | 2 +- 18 files changed, 210 insertions(+), 102 deletions(-) diff --git a/Source/Thunder/Controller.cpp b/Source/Thunder/Controller.cpp index 04ab088c8..d0964c046 100644 --- a/Source/Thunder/Controller.cpp +++ b/Source/Thunder/Controller.cpp @@ -1216,22 +1216,27 @@ namespace Plugin { return (Core::ERROR_NONE); } - Core::hresult Controller::Proxies(const uint32_t linkId, IMetadata::Data::IProxiesIterator*& outProxies) const + Core::hresult Controller::Proxies(const Core::OptionalType& linkId, IMetadata::Data::IProxiesIterator*& outProxies) const { Core::hresult result = Core::ERROR_UNKNOWN_KEY; std::vector collection; - bool proxySearch = RPC::Administrator::Instance().Allocations(linkId, [&collection](const std::vector& proxies) { + bool proxySearch = RPC::Administrator::Instance().Allocations(linkId.IsSet() ? linkId.Value() : EMPTY_STRING, [&collection, &linkId](const string& origin, const std::vector& proxies) { for (const auto& proxy : proxies) { IMetadata::Data::Proxy data; data.Count = proxy->ReferenceCount(); data.Instance = proxy->Implementation(); data.Interface = proxy->InterfaceId(); data.Name = proxy->Name(); + if (linkId.IsSet() == false) { + data.Origin = Core::NumberType(proxy->ChannelId()).Text() + '@' + origin; + } collection.emplace_back(std::move(data)); } }); + TRACE(Trace::Information, (_T("Found %d proxies to be listed and the search = [%s]"), collection.size(), proxySearch ? _T("true") : _T("false"))); + if (proxySearch == true) { using Iterator = IMetadata::Data::IProxiesIterator; @@ -1440,6 +1445,8 @@ namespace Plugin { buildInfo.ThreadPoolCount = THREADPOOL_COUNT; #endif + buildInfo.COMRPCTimeOut = RPC::CommunicationTimeOut; + return (Core::ERROR_NONE); } } diff --git a/Source/Thunder/Controller.h b/Source/Thunder/Controller.h index 3063e5850..3ea2df158 100644 --- a/Source/Thunder/Controller.h +++ b/Source/Thunder/Controller.h @@ -328,7 +328,7 @@ namespace Plugin { // IMetadata overrides Core::hresult Links(IMetadata::Data::ILinksIterator*& links) const override; - Core::hresult Proxies(const uint32_t linkId, IMetadata::Data::IProxiesIterator*& proxies) const override; + Core::hresult Proxies(const Core::OptionalType& linkId, IMetadata::Data::IProxiesIterator*& proxies) const override; Core::hresult Services(const Core::OptionalType& callsign, IMetadata::Data::IServicesIterator*& services) const override; Core::hresult CallStack(const uint8_t threadId, IMetadata::Data::ICallStackIterator*& callstack) const override; Core::hresult Threads(IMetadata::Data::IThreadsIterator*& threads) const override; diff --git a/Source/Thunder/ExampleConfigWindows.json b/Source/Thunder/ExampleConfigWindows.json index a5f943668..87d01da86 100644 --- a/Source/Thunder/ExampleConfigWindows.json +++ b/Source/Thunder/ExampleConfigWindows.json @@ -3,16 +3,16 @@ "binding": "127.0.0.1", "idletime": 60, "ipv6": false, - "persistentpath": "C:/ThunderWin/artifacts/Persistent", - "volatilepath": "C:/ThunderWin/artifacts/temp", - "datapath": "C:/ThunderWin/artifacts/Debug/Plugins", - "systempath": "C:/ThunderWin/artifacts/Debug", - "proxystubpath": "C:/ThunderWin/artifacts/ProxyStubs/Debug", + "persistentpath": "D:/domotica/artifacts/Persistent", + "volatilepath": "D:/domotica//artifacts/temp", + "datapath": "D:/domotica/artifacts/Debug/Plugins", + "systempath": "D:/domotica/artifacts/Debug", + "proxystubpath": "D:/domotica/artifacts/ProxyStubs/Debug", "communicator": "127.0.0.1:62000", "redirect": "Service/Controller/UI", "observe": { - "proxystubpath": "C:/ThunderWin/artifacts/dynamic/proxystubs", - "configpath": "C:/ThunderWin/artifacts/dynamic/config" + "proxystubpath": "D:/domotica/artifacts/dynamic/proxystubs", + "configpath": "D:/domotica/artifacts/dynamic/config" }, "messaging": { "port": 63000, @@ -137,7 +137,7 @@ "callsign": "Butler", "locator": "libButler.so", "classname": "Butler", - "startmode": "Activated" + "startmode": "Deactivated" }, { "callsign": "ZigbeeControl", @@ -154,10 +154,10 @@ "callsign": "ZWaveControl", "locator": "libZWaveControl.so", "classname": "ZWaveControl", - "startmode": "Activated", + "startmode": "Deactivated", "configuration": { "port": "\\\\.\\COM4", - "key": "ba:09:87:65:43:21:de:ad:be:ef:12:34:56:78:90:ab" + "key": "ba:09:87:65:43:21:de:ad:be:ef:12:34:56:78:90:ab" } }, { @@ -401,7 +401,7 @@ "sleep": "5", "single": false, "crash": true, - "leak": true, + "leak": true, "root": { "mode": "Local" } @@ -458,7 +458,7 @@ "callsign": "WebServer", "locator": "libWebServer.so", "classname": "WebServer", - "startmode": "Deactivated", + "startmode": "Activated", "communicator": "127.0.0.1:2349", "configuration": { "port": 8080, @@ -571,12 +571,6 @@ "classname": "MessageControl", "startmode": "Activated" }, - { - "callsign": "TraceControl", - "locator": "libtracecontrol.so", - "classname": "TraceControl", - "startmode": "Deactivated" - }, { "callsign": "RemoteControl", "locator": "libremotecontrol.so", diff --git a/Source/Thunder/PluginHost.cpp b/Source/Thunder/PluginHost.cpp index abbb9c6a7..5e9b84341 100644 --- a/Source/Thunder/PluginHost.cpp +++ b/Source/Thunder/PluginHost.cpp @@ -712,10 +712,10 @@ POP_WARNING() printf("Link: %s\n", index.Current().Remote.Value().c_str()); printf("------------------------------------------------------------\n"); - RPC::Administrator::Instance().Allocations(index.Current().ID.Value(), [](const std::vector& proxies) { + RPC::Administrator::Instance().Allocations(index.Current().Name.Value(), [](const string& origin, const std::vector& proxies) { for (const auto& proxy: proxies) { Core::instance_id instanceId = proxy->Implementation(); - printf("[%s] InstanceId: 0x%" PRIx64 ", RefCount: %d, InterfaceId %d [0x%X]\n", proxy->Name().c_str(), static_cast(instanceId), proxy->ReferenceCount(), proxy->InterfaceId(), proxy->InterfaceId()); + printf("[%s] InstanceId: 0x%" PRIx64 ", RefCount: %d, InterfaceId %d [0x%X], Origin: %s\n", proxy->Name().c_str(), static_cast(instanceId), proxy->ReferenceCount(), proxy->InterfaceId(), proxy->InterfaceId(), origin.c_str()); } printf("\n"); }); diff --git a/Source/Thunder/PluginServer.h b/Source/Thunder/PluginServer.h index fef22a2ad..9ddc623bb 100644 --- a/Source/Thunder/PluginServer.h +++ b/Source/Thunder/PluginServer.h @@ -532,10 +532,11 @@ namespace PluginHost { ExternalAccess& operator=(const ExternalAccess&) = delete; ExternalAccess( - const Core::NodeId& source, + const Core::NodeId& sourceNode, const string& proxyStubPath, - const Core::ProxyType& handler) - : RPC::Communicator(source, proxyStubPath, Core::ProxyType(handler)) + const Core::ProxyType& handler, + const string& sourceName) + : RPC::Communicator(sourceNode, proxyStubPath, Core::ProxyType(handler), sourceName.c_str()) , _plugin(nullptr) { } ~ExternalAccess() override = default; @@ -822,7 +823,7 @@ namespace PluginHost { , _lastId(0) , _metadata(plugin.MaxRequests.Value()) , _library() - , _external(PluginNodeId(server, plugin), server.ProxyStubPath(), handler) + , _external(PluginNodeId(server, plugin), server.ProxyStubPath(), handler, '/' + Callsign()) , _administrator(administrator) , _composit(*this) , _jobs(administrator) @@ -855,6 +856,9 @@ namespace PluginHost { } public: + inline const RPC::Communicator& COMServer() const { + return (_external); + } inline void Submit(Core::ProxyType&& job) { _jobs.Push(std::move(job)); } @@ -2205,7 +2209,7 @@ namespace PluginHost { const uint8_t hardKillCheckWaitTime, const bool delegatedReleases, const Core::ProxyType& handler) - : RPC::Communicator(node, ProxyStubPathCreator(proxyStubPath, observableProxyStubPath), Core::ProxyType(handler)) + : RPC::Communicator(node, ProxyStubPathCreator(proxyStubPath, observableProxyStubPath), Core::ProxyType(handler), _T("/")) , _parent(parent) , _persistentPath(persistentPath) , _systemPath(systemPath) @@ -3203,10 +3207,24 @@ namespace PluginHost { entry.Activity = element.Source().IsOpen(); entry.State = Metadata::Channel::state::COMRPC; - entry.Name = string("/" EXPAND_AND_QUOTE(APPLICATION_NAME) "/Communicator"); + entry.Name = element.Extension().Origin(); entry.Remote = element.Source().RemoteId(); }); - _adminLock.Unlock(); + + for (const auto& entry : _services) { + entry.second->COMServer().Visit([&](const RPC::Communicator::Client& element) + { + Metadata::Channel& entry = metaData.Add(); + entry.ID = element.Extension().Id(); + + entry.Activity = element.Source().IsOpen(); + entry.State = Metadata::Channel::state::COMRPC; + entry.Name = element.Extension().Origin(); + entry.Remote = element.Source().RemoteId(); + }); + } + + _adminLock.Unlock(); } uint32_t FromIdentifier(const string& callSign, Core::ProxyType& service) { diff --git a/Source/com/Administrator.cpp b/Source/com/Administrator.cpp index 8ef34abcc..3f03b6e7d 100644 --- a/Source/com/Administrator.cpp +++ b/Source/com/Administrator.cpp @@ -19,10 +19,13 @@ #include "Administrator.h" #include "IUnknown.h" +#include "Communicator.h" namespace Thunder { namespace RPC { + /* static */ const string Administrator::DanglingId("/Dangling"); + Administrator::Administrator() : _adminLock() , _stubs() @@ -122,17 +125,17 @@ namespace RPC { ChannelMap::iterator index(_channelProxyMap.find(proxy.Id())); if (index != _channelProxyMap.end()) { - Proxies::iterator entry(index->second.begin()); - while ((entry != index->second.end()) && ((*entry) != &proxy)) { + Proxies::iterator entry(index->second.second.begin()); + while ((entry != index->second.second.end()) && ((*entry) != &proxy)) { entry++; } - ASSERT(entry != index->second.end()); + ASSERT(entry != index->second.second.end()); - if (entry != index->second.end()) { - index->second.erase(entry); + if (entry != index->second.second.end()) { + index->second.second.erase(entry); removed = true; - if (index->second.size() == 0) { + if (index->second.second.size() == 0) { _channelProxyMap.erase(index); } } @@ -228,11 +231,11 @@ namespace RPC { ChannelMap::iterator index(_channelProxyMap.find(channel->Id())); if (index != _channelProxyMap.end()) { - Proxies::iterator entry(index->second.begin()); - while ((entry != index->second.end()) && (((*entry)->InterfaceId() != id) || ((*entry)->Implementation() != impl))) { + Proxies::iterator entry(index->second.second.begin()); + while ((entry != index->second.second.end()) && (((*entry)->InterfaceId() != id) || ((*entry)->Implementation() != impl))) { entry++; } - if (entry != index->second.end()) { + if (entry != index->second.second.end()) { interface = (*entry)->QueryInterface(id); if (interface != nullptr) { result = (*entry); @@ -261,11 +264,11 @@ namespace RPC { ChannelMap::iterator index(_channelProxyMap.find(channelId)); if (index != _channelProxyMap.end()) { - Proxies::iterator entry(index->second.begin()); - while ((entry != index->second.end()) && (((*entry)->InterfaceId() != id) || ((*entry)->Implementation() != impl))) { + Proxies::iterator entry(index->second.second.begin()); + while ((entry != index->second.second.end()) && (((*entry)->InterfaceId() != id) || ((*entry)->Implementation() != impl))) { entry++; } - if (entry != index->second.end()) { + if (entry != index->second.second.end()) { interface = (*entry)->Acquire(outbound, id); // The implementation could be found, but the current implemented proxy is not @@ -287,7 +290,18 @@ namespace RPC { ASSERT(result != nullptr); // Register it as it is remotely registered :-) - _channelProxyMap[channelId].push_back(result); + ChannelMap::iterator channelIndex(_channelProxyMap.find(channelId)); + + if (channelIndex != _channelProxyMap.end()) { + channelIndex->second.second.push_back(result); + } + else { + Proxies baseList; + baseList.emplace_back(result); + _channelProxyMap.emplace(std::piecewise_construct, + std::forward_as_tuple(channelId), + std::forward_as_tuple(std::pair(channel->Origin(), baseList))); + } // This will increment the reference count to 2 (one in the ChannelProxyMap and one in the QueryInterface ). interface = result->QueryInterface(id); @@ -431,7 +445,7 @@ namespace RPC { ChannelMap::iterator index(_channelProxyMap.find(channelId)); if (index != _channelProxyMap.end()) { - for (auto entry : index->second) { + for (auto entry : index->second.second) { entry->Invalidate(); _danglingProxies.emplace_back(entry); @@ -444,7 +458,7 @@ namespace RPC { // the pendingProxies. The receiver of pendingProxies has to take // care of releasing the last reference we, as administration layer // hold upon this.. - pendingProxies = std::move(index->second); + pendingProxies = std::move(index->second.second); _channelProxyMap.erase(index); } diff --git a/Source/com/Administrator.h b/Source/com/Administrator.h index 95b5eeea0..422cc10b0 100644 --- a/Source/com/Administrator.h +++ b/Source/com/Administrator.h @@ -124,8 +124,10 @@ namespace RPC { }; public: + static const string DanglingId; + using Proxies = std::vector; - using ChannelMap = std::unordered_map; + using ChannelMap = std::unordered_map >; using ReferenceMap = std::unordered_map >; using Stubs = std::unordered_map; using Factories = std::unordered_map; @@ -149,25 +151,31 @@ namespace RPC { } template - bool Allocations(const uint32_t id, ACTION&& action) const { + bool Allocations(const string& linkId, ACTION&& action) const { bool found = false; _adminLock.Lock(); - if (id == 0) { + if (linkId.empty() == true) { for (const auto& proxy : _channelProxyMap) { - action(proxy.second); + action(proxy.second.first, proxy.second.second); } - action(_danglingProxies); + action(DanglingId, _danglingProxies); found = true; } + else if (linkId == DanglingId) { + action(DanglingId, _danglingProxies); + found = true; + } else { ChannelMap::const_iterator index(_channelProxyMap.begin()); while ((found == false) && (index != _channelProxyMap.end())) { - if (index->first != id) { + ASSERT(index->second.second.size() != 0); + + if (index->second.first != linkId) { index++; } else { found = true; - action(index->second); + action(index->second.first, index->second.second); } } } diff --git a/Source/com/Communicator.cpp b/Source/com/Communicator.cpp index 8e156fc12..3740bc0d2 100644 --- a/Source/com/Communicator.cpp +++ b/Source/com/Communicator.cpp @@ -362,8 +362,9 @@ namespace RPC { uint8_t Communicator::_hardKillCheckWaitTime = 4; PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) - Communicator::Communicator(const Core::NodeId& node, const string& proxyStubPath) - : _connectionMap(*this) + Communicator::Communicator(const Core::NodeId& node, const string& proxyStubPath, const TCHAR* sourceName) + : _source(sourceName == nullptr ? _T("UnknownServer") : sourceName) + , _connectionMap(*this) , _ipcServer(node, _connectionMap, proxyStubPath) { if (proxyStubPath.empty() == false) { RPC::LoadProxyStubs(proxyStubPath); @@ -374,10 +375,12 @@ namespace RPC { } Communicator::Communicator( - const Core::NodeId& node, + const Core::NodeId& node, const string& proxyStubPath, - const Core::ProxyType& handler) - : _connectionMap(*this) + const Core::ProxyType& handler, + const TCHAR* sourceName) + : _source(sourceName == nullptr ? _T("UnknownServer") : sourceName) + , _connectionMap(*this) , _ipcServer(node, _connectionMap, proxyStubPath, handler) { if (proxyStubPath.empty() == false) { RPC::LoadProxyStubs(proxyStubPath); @@ -416,7 +419,7 @@ namespace RPC { PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) CommunicatorClient::CommunicatorClient( const Core::NodeId& remoteNode) - : Core::IPCChannelClientType(remoteNode, CommunicationBufferSize) + : BaseClass(remoteNode, CommunicationBufferSize) , _announceMessage() , _announceEvent(false, true) , _connectionId(~0) @@ -432,7 +435,7 @@ namespace RPC { CommunicatorClient::CommunicatorClient( const Core::NodeId& remoteNode, const Core::ProxyType& handler) - : Core::IPCChannelClientType(remoteNode, CommunicationBufferSize) + : BaseClass(remoteNode, CommunicationBufferSize) , _announceMessage() , _announceEvent(false, true) , _connectionId(~0) diff --git a/Source/com/Communicator.h b/Source/com/Communicator.h index e6439a279..1f157c361 100644 --- a/Source/com/Communicator.h +++ b/Source/com/Communicator.h @@ -105,7 +105,7 @@ namespace RPC { RPC::Environment::Value = value; RPC::Environment::Scope = scoping; } - Environment(Environment&& move) { + Environment(Environment&& move) noexcept { RPC::Environment::Key = std::move(move.RPC::Environment::Key); RPC::Environment::Value = std::move(move.RPC::Environment::Value); RPC::Environment::Scope = std::move(move.RPC::Environment::Scope); @@ -117,7 +117,7 @@ namespace RPC { } ~Environment() = default; - Environment& operator= (Environment&& move) { + Environment& operator= (Environment&& move) noexcept { RPC::Environment::Key = std::move(move.RPC::Environment::Key); RPC::Environment::Value = std::move(move.RPC::Environment::Value); RPC::Environment::Scope = std::move(move.RPC::Environment::Scope); @@ -351,7 +351,7 @@ namespace RPC { { return (_environments); } - inline void Environments(const std::vector& environments) { + inline void Environments(std::vector&& environments) { _environments = std::move(environments); } @@ -568,7 +568,10 @@ namespace RPC { } uint32_t Id() const { - return _id; + return (_channel.Descriptor()); + } + string Origin() const { + return (_connectionMap->Origin()); } private: @@ -1187,6 +1190,9 @@ namespace RPC { } public: + const string& Origin() const { + return (_parent.Origin()); + } inline void Register(RPC::IRemoteConnection::INotification* sink) { ASSERT(sink != nullptr); @@ -1651,12 +1657,14 @@ POP_WARNING() Communicator( const Core::NodeId& node, - const string& proxyStubPath); + const string& proxyStubPath, + const TCHAR* sourceName = nullptr); Communicator( const Core::NodeId& node, const string& proxyStubPath, - const Core::ProxyType& handler); - virtual ~Communicator(); + const Core::ProxyType& handler, + const TCHAR* sourceName = nullptr); + virtual ~Communicator(); public: // void action(const Client& client) @@ -1669,6 +1677,9 @@ POP_WARNING() void Visit(ACTION&& action) const { _ipcServer.Visit(action); } + const string& Origin() const { + return (_source); + } inline bool IsListening() const { return (_ipcServer.IsListening()); @@ -1753,15 +1764,45 @@ POP_WARNING() } private: + const string _source; RemoteConnectionMap _connectionMap; ChannelServer _ipcServer; static uint8_t _softKillCheckWaitTime; static uint8_t _hardKillCheckWaitTime; }; - class EXTERNAL CommunicatorClient : public Core::IPCChannelClientType, public Core::IDispatchType { + class EXTERNAL ClientMetadata { + public: + ClientMetadata() = delete; + ClientMetadata(ClientMetadata&&) = delete; + ClientMetadata(const ClientMetadata&) = delete; + ClientMetadata& operator=(ClientMetadata&&) = delete; + ClientMetadata& operator=(const ClientMetadata&) = delete; + + ClientMetadata(Core::IPCChannelType* channel) + : _socketPort(channel->Source()) + { + } + ~ClientMetadata() = default; + + public: + uint32_t Id() const + { + return (_socketPort.Descriptor()); + } + string Origin() const { + return (_socketPort.RemoteId()); + } + + private: + // Non ref-counted reference to our parent, of which we are a composit :-) + Core::SocketPort& _socketPort; + }; + + + class EXTERNAL CommunicatorClient : public Core::IPCChannelClientType, public Core::IDispatchType { private: - typedef Core::IPCChannelClientType BaseClass; + using BaseClass = Core::IPCChannelClientType; class AnnounceHandler : public Core::IIPCServer { public: diff --git a/Source/com/IUnknown.cpp b/Source/com/IUnknown.cpp index bb09281af..c09638b06 100644 --- a/Source/com/IUnknown.cpp +++ b/Source/com/IUnknown.cpp @@ -99,20 +99,13 @@ namespace ProxyStub { // ------------------------------------------------------------------------------------------- // PROXY // ------------------------------------------------------------------------------------------- - const Core::SocketPort* UnknownProxy::Socket() const + uint32_t UnknownProxy::Id() const { - const Core::SocketPort* result = nullptr; - - _adminLock.Lock(); + uint32_t id = 0; if (_channel.IsValid() == true) { - const RPC::Communicator::Client* comchannel = dynamic_cast(_channel.operator->()); - if (comchannel != nullptr) { - result = &(comchannel->Source()); - } + id = _channel->Id(); } - _adminLock.Unlock(); - - return (result); + return (id); } static class UnknownInstantiation { diff --git a/Source/com/IUnknown.h b/Source/com/IUnknown.h index e46f13269..5f33e5df6 100644 --- a/Source/com/IUnknown.h +++ b/Source/com/IUnknown.h @@ -272,7 +272,6 @@ namespace ProxyStub { { return (&_parent); } - const Core::SocketPort* Socket() const; void* Interface(const Core::instance_id& implementation, const uint32_t id) const { void* result = nullptr; @@ -287,6 +286,12 @@ namespace ProxyStub { { return (_implementation); } + inline uint32_t ChannelId() const + { + Core::SafeSyncType lock(_adminLock); + + return (_channel.IsValid() ? _channel->Id() : ~0); + } // Required by proxystubs! const Core::ProxyType& Channel() const { return (_channel); @@ -426,16 +431,13 @@ namespace ProxyStub { return (_parent.QueryInterface(id)); } - // The RPC::Administrator uses this to identifiy to what link this + // The RPC::Administrator uses this to identifiy to what link this // proxy belongs. The LinkId is always called within the lock of the // RPC::Administrator, and since it is onl used and called from there // and the clearing of the _channel is also only called from there, // Invalidate(), It is safe to use it on the _channel in an unlocked // fashion!! - uint32_t Id() const - { - return (_channel.IsValid() ? _channel->Id() : 0); - } + uint32_t Id() const; void Invalidate() { ASSERT(_refCount > 0); _adminLock.Lock(); diff --git a/Source/core/IPCConnector.h b/Source/core/IPCConnector.h index d50420872..32567e625 100644 --- a/Source/core/IPCConnector.h +++ b/Source/core/IPCConnector.h @@ -760,6 +760,7 @@ POP_WARNING() } virtual uint32_t Id() const = 0; + virtual string Origin() const = 0; virtual uint32_t ReportResponse(Core::ProxyType& inbound) = 0; private: @@ -923,6 +924,10 @@ POP_WARNING() uint32_t Id() const override { return (__Id()); } + string Origin() const override { + return (__Origin()); + } + uint32_t ReportResponse(Core::ProxyType& inbound) override { // We got the event, start the invoke, wait for the event to be set again.. @@ -968,6 +973,23 @@ POP_WARNING() return (0); } + IS_MEMBER_AVAILABLE(Origin, hasOrigin); + + template + typename Core::TypeTraits::enable_if ::value, string>::type + __Origin() const + { + return (_extension.Origin()); + } + + template + typename Core::TypeTraits::enable_if ::value, string>::type + __Origin() const + { + static string unknown(_T("Unknown")); + return (unknown); + } + uint32_t Execute(const ProxyType& command, IDispatchType* completed) override { uint32_t success = Core::ERROR_UNAVAILABLE; diff --git a/Source/core/SocketPort.h b/Source/core/SocketPort.h index efadf89bb..2f3f51b31 100644 --- a/Source/core/SocketPort.h +++ b/Source/core/SocketPort.h @@ -250,6 +250,10 @@ namespace Thunder { NodeId Accept(); void Listen(); SOCKET Accept(NodeId& remoteId); + IResource::handle Descriptor() const override + { + return (static_cast(m_Socket)); + } protected: virtual uint32_t Initialize(); @@ -267,10 +271,6 @@ namespace Thunder { private: string Identifier(const NodeId& node) const; - IResource::handle Descriptor() const override - { - return (static_cast(m_Socket)); - } inline uint32_t SocketMode() const { return (((m_SocketType == LISTEN) || (m_SocketType == STREAM)) ? SOCK_STREAM : ((m_SocketType == DATAGRAM) ? SOCK_DGRAM : (m_SocketType == SEQUENCED ? SOCK_SEQPACKET : SOCK_RAW))); diff --git a/Source/core/SocketServer.h b/Source/core/SocketServer.h index aca3a38ab..0b439618c 100644 --- a/Source/core/SocketServer.h +++ b/Source/core/SocketServer.h @@ -114,7 +114,7 @@ namespace Core { } inline uint32_t Count() const { - return (_clients.size()); + return (static_cast(_clients.size())); } HANDLECLIENT Client() { diff --git a/Source/plugins/IController.h b/Source/plugins/IController.h index e389a55aa..56901f3ef 100644 --- a/Source/plugins/IController.h +++ b/Source/plugins/IController.h @@ -260,6 +260,7 @@ namespace Controller { uint8_t InstanceIDBits /* @brief Core instance bits */; Core::OptionalType TraceLevel /* @brief Trace level */; uint8_t ThreadPoolCount /* Number of configured threads on the threadpool */; + uint32_t COMRPCTimeOut /* The number of milliseconds a COMRPC call can take before it is assumed to fail */; }; struct CallStack { @@ -280,6 +281,7 @@ namespace Controller { string Name /* @brief The fully qualified name of the interface */; Core::instance_id Instance /* @brief Instance ID */; uint32_t Count /* @brief Reference count */; + Core::OptionalType Origin /* @brief The Origin of the assocated connection */; }; struct Link { @@ -294,9 +296,9 @@ namespace Controller { string Remote /* @brief IP address (or FQDN) of the other side of the connection */; state State /* @brief State of the link */; - Core::OptionalType Name /* @brief Name of the connection */; uint32_t Id /* @brief A unique number identifying the connection */; bool Activity /* @brief Denotes if there was any activity on this connection */; + Core::OptionalType Name /* @brief Name of the connection */; }; struct Service { @@ -354,12 +356,12 @@ namespace Controller { virtual Core::hresult Services(const Core::OptionalType& callsign /* @index */, Data::IServicesIterator*& services /* @out @extract */) const = 0; // @property - // @brief Connections list + // @brief Connections list of Thunder connections virtual Core::hresult Links(Data::ILinksIterator*& links /* @out */) const = 0; // @property // @brief Proxies list - virtual Core::hresult Proxies(const uint32_t linkID /* @index */, Data::IProxiesIterator*& proxies /* @out */) const = 0; + virtual Core::hresult Proxies(const Core::OptionalType& linkID /* @index */, Data::IProxiesIterator*& proxies /* @out */) const = 0; // @property // @brief Framework version diff --git a/Source/plugins/IShell.h b/Source/plugins/IShell.h index 8c03770e6..b850c0409 100644 --- a/Source/plugins/IShell.h +++ b/Source/plugins/IShell.h @@ -77,24 +77,24 @@ namespace PluginHost { virtual void Unregister(const INotification* sink) = 0; }; - enum class startmode : uint8_t { - UNAVAILABLE, - DEACTIVATED, - ACTIVATED - }; - // State of the IPlugin interface associated with this shell. enum state : uint8_t { UNAVAILABLE, DEACTIVATED, - DEACTIVATION, ACTIVATED, + DEACTIVATION, ACTIVATION, PRECONDITION, HIBERNATED, DESTROYED }; + enum class startmode : uint8_t { + UNAVAILABLE = static_cast(state::UNAVAILABLE), + DEACTIVATED = static_cast(state::DEACTIVATED), + ACTIVATED = static_cast(state::ACTIVATED) + }; + enum reason : uint8_t { REQUESTED, AUTOMATIC, diff --git a/Source/plugins/plugins.vcxproj b/Source/plugins/plugins.vcxproj index 378a1e795..4ca92589e 100755 --- a/Source/plugins/plugins.vcxproj +++ b/Source/plugins/plugins.vcxproj @@ -50,6 +50,10 @@ true false true + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --case-convention legacy --no-includes --keep-empty -c --namespace Thunder::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --case-convention legacy --no-includes --keep-empty -c --namespace Thunder::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --case-convention legacy --no-includes --keep-empty -c --namespace Thunder::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force + python "$(ToolPath)\JsonGenerator\JsonGenerator.py" -I "$(FrameworkPath)\" --case-convention legacy --no-includes --keep-empty -c --namespace Thunder::Exchange::Controller -o "$(ProjectDir)/json" "%(FullPath)" --force $(ProjectDir)json/JDispatcher.h @@ -314,4 +318,4 @@ - + \ No newline at end of file diff --git a/Tests/unit/core/test_rpc.cpp b/Tests/unit/core/test_rpc.cpp index 83cd7c632..fdd703057 100644 --- a/Tests/unit/core/test_rpc.cpp +++ b/Tests/unit/core/test_rpc.cpp @@ -224,7 +224,7 @@ namespace Exchange { ExternalAccess& operator=(const ExternalAccess &) = delete; ExternalAccess(const ::Thunder::Core::NodeId & source) - : ::Thunder::RPC::Communicator(source, _T("")) + : ::Thunder::RPC::Communicator(source, _T(""), _T("@test")) { Open(::Thunder::Core::infinite); }