Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Source/websocket/JSONRPCLink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@

namespace WPEFramework {

namespace JSONRPC {

// Shared channel map stored in the library's data segment.
// This ensures all DSOs using JSONRPCLink share the same map instance,
// preventing crashes when plugins unload while others still hold references.
Core::ProxyMapType<string, CommunicationChannelBase>& GetChannelMap()
{
static Core::ProxyMapType<string, CommunicationChannelBase> channelMap;
return channelMap;
}

} // namespace JSONRPC

ENUM_CONVERSION_BEGIN(WPEFramework::JSONRPC::JSONPluginState)

{ WPEFramework::JSONRPC::DEACTIVATED, _TXT("Deactivated") },
Expand Down
20 changes: 14 additions & 6 deletions Source/websocket/JSONRPCLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,21 @@ namespace WPEFramework {

using namespace Core::TypeTraits;

// Base class for CommunicationChannel to allow shared storage across DSO boundaries
class EXTERNAL CommunicationChannelBase {
public:
virtual ~CommunicationChannelBase() = default;
};

// Returns the shared channel map stored in the library's data segment
EXTERNAL Core::ProxyMapType<string, CommunicationChannelBase>& GetChannelMap();

template<typename INTERFACE>
class LinkType {
private:
typedef std::function<void(const Core::JSONRPC::Message&)> CallbackFunction;

class CommunicationChannel {
class CommunicationChannel : public CommunicationChannelBase {
private:
// -----------------------------------------------------------------------------------------------
// Create a resource allocator for all JSON objects used in these tests
Expand Down Expand Up @@ -198,14 +207,13 @@ namespace WPEFramework {
}

public:
virtual ~CommunicationChannel() = default;
~CommunicationChannel() override = default;
static Core::ProxyType<CommunicationChannel> Instance(const Core::NodeId& remoteNode, const string& callsign, const string& query)
{
Comment on lines +210 to 212
static Core::ProxyMapType<string, CommunicationChannel> channelMap;

string searchLine = remoteNode.HostAddress() + '@' + callsign;
// Use type-discriminated key to prevent collisions between different INTERFACE types
string searchLine = remoteNode.HostAddress() + '@' + callsign + '@' + typeid(INTERFACE).name();

return (channelMap.template Instance<CommunicationChannel>(searchLine, remoteNode, callsign, query));
return Core::ProxyType<CommunicationChannel>(GetChannelMap().template Instance<CommunicationChannel>(searchLine, remoteNode, callsign, query));
}

Comment on lines 215 to 218
public:
Expand Down
Loading