Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
4 changes: 2 additions & 2 deletions Source/Thunder/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ namespace Plugin {
}
}

_service->Register(&_systemInfoReport);
_service->Register(static_cast<PluginHost::IPlugin::INotification*>(&_systemInfoReport));

if (config.Ui.Value() == true) {
_service->EnableWebServer(_T("UI"), EMPTY_STRING);
Expand Down Expand Up @@ -180,7 +180,7 @@ namespace Plugin {
_probe = nullptr;
}

_service->Unregister(&_systemInfoReport);
_service->Unregister(static_cast<PluginHost::IPlugin::INotification*>(&_systemInfoReport));

/* stop the file serving over http.... */
service->DisableWebServer();
Expand Down
10 changes: 10 additions & 0 deletions Source/Thunder/Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ namespace Plugin {

class Sink
: public PluginHost::IPlugin::INotification
, public PluginHost::IPlugin::INotificationExtended
, public PluginHost::ISubSystem::INotification {
private:
class Job {
Expand Down Expand Up @@ -109,9 +110,18 @@ namespace Plugin {
{
_parent.NotifyStateChange(callsign, PluginHost::IShell::UNAVAILABLE, plugin->Reason());
}
void Hibernated(const string& callsign, PluginHost::IShell* plugin) override
{
_parent.NotifyStateChange(callsign, PluginHost::IShell::HIBERNATED, plugin->Reason());
}
void Destroyed(const string& callsign, PluginHost::IShell* plugin) override
{
_parent.NotifyStateChange(callsign, PluginHost::IShell::DESTROYED, plugin->Reason());
}

BEGIN_INTERFACE_MAP(Sink)
INTERFACE_ENTRY(PluginHost::IPlugin::INotification)
INTERFACE_ENTRY(PluginHost::IPlugin::INotificationExtended)
END_INTERFACE_MAP

private:
Expand Down
25 changes: 25 additions & 0 deletions Source/Thunder/PluginServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,19 +319,43 @@ namespace PluginHost {
void Server::Service::Register(IPlugin::INotification * sink, const Core::OptionalType<string>& callsign) /* override */
{
_administrator.Register(sink, callsign);

IPlugin::INotificationExtended* extended = sink->QueryInterface<IPlugin::INotificationExtended>();
if (extended != nullptr) {
_administrator.Register(extended, callsign);
extended->Release();
}
Comment on lines 319 to +327
}

void Server::Service::Unregister(IPlugin::INotification * sink, const Core::OptionalType<string>& callsign) /* override */
{
IPlugin::INotificationExtended* extended = sink->QueryInterface<IPlugin::INotificationExtended>();
if (extended != nullptr) {
_administrator.Unregister(extended, callsign);
extended->Release();
}

_administrator.Unregister(sink, callsign);
}

void Server::Service::Register(IPlugin::INotification * sink, const uint32_t interface_id)
{
_administrator.Register(sink, interface_id);

IPlugin::INotificationExtended* extended = sink->QueryInterface<IPlugin::INotificationExtended>();
if (extended != nullptr) {
_administrator.Register(extended, interface_id);
extended->Release();
}
}
void Server::Service::Unregister(IPlugin::INotification * sink, const uint32_t interface_id)
{
IPlugin::INotificationExtended* extended = sink->QueryInterface<IPlugin::INotificationExtended>();
if (extended != nullptr) {
_administrator.Unregister(extended, interface_id);
extended->Release();
}

_administrator.Unregister(sink, interface_id);
}

Expand Down Expand Up @@ -797,6 +821,7 @@ namespace PluginHost {
// Both branches are reachable when HIBERNATE_ENABLED is defined.
if (result == Core::ERROR_NONE) {
if (State() == IShell::state::HIBERNATED) {
_administrator.Hibernated(Callsign(), this);
SYSLOG(Logging::Startup, ("Hibernated plugin [%s]:[%s]", ClassName().c_str(), Callsign().c_str()));
} else {
// wakeup occured right after hibernation finished
Expand Down
69 changes: 54 additions & 15 deletions Source/Thunder/PluginServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ namespace PluginHost {
// It's reference counted, so just take it out of the list, state to DESTROYED
// Also unsubscribe all subscribers. They need to go..
State(DESTROYED);
_administrator.Destroyed(Callsign(), this);

Comment on lines 960 to 964
Comment on lines 960 to 964
Unlock();
}
Expand Down Expand Up @@ -2663,6 +2664,7 @@ namespace PluginHost {
};
};

template <typename NOTIFICATION>
class Notifiers
{
public:
Expand All @@ -2688,7 +2690,7 @@ namespace PluginHost {

//return true when added
template <typename... Args>
bool Add(PluginHost::IPlugin::INotification* notification, Args&&... args)
bool Add(NOTIFICATION* notification, Args&&... args)
{
_notificationLock.Lock();

Expand All @@ -2710,16 +2712,16 @@ namespace PluginHost {

// return true when removed
template <typename... Args>
bool Remove(const PluginHost::IPlugin::INotification* const notification, Args&&... args)
bool Remove(const NOTIFICATION* const notification, Args&&... args)
{
bool found = false;

_notificationLock.Lock();

auto range = _notifiers.equal_range(const_cast<PluginHost::IPlugin::INotification*>(notification));
auto range = _notifiers.equal_range(const_cast<NOTIFICATION*>(notification));
for (auto it = range.first; it != range.second; ++it) {
if (it->second.IsEqual(std::forward<Args>(args)...) == true) {
PluginHost::IPlugin::INotification* foundnotification = it->first;
NOTIFICATION* foundnotification = it->first;
_notifiers.erase(it);
foundnotification->Release();
foundnotification = nullptr;
Expand All @@ -2731,14 +2733,14 @@ namespace PluginHost {

return found;
}
void RemoveAll(const PluginHost::IPlugin::INotification* const notification)
void RemoveAll(const NOTIFICATION* const notification)
{
_notificationLock.Lock();

auto range = _notifiers.equal_range(const_cast<PluginHost::IPlugin::INotification*>(notification));
auto range = _notifiers.equal_range(const_cast<NOTIFICATION*>(notification));
auto it = range.first;
while (it != range.second) {
PluginHost::IPlugin::INotification* foundnotification = it->first;
NOTIFICATION* foundnotification = it->first;
it = _notifiers.erase(it);
foundnotification->Release();
foundnotification = nullptr;
Expand All @@ -2753,7 +2755,7 @@ namespace PluginHost {
auto it = _notifiers.begin();
while (it != _notifiers.end()) {
if (static_cast<const Core::IUnknown*>(it->first) == notification) {
PluginHost::IPlugin::INotification* foundnotification = it->first;
NOTIFICATION* foundnotification = it->first;
it = _notifiers.erase(it);
foundnotification->Release();
foundnotification = nullptr;
Expand All @@ -2764,7 +2766,7 @@ namespace PluginHost {

_notificationLock.Unlock();
}
void Notify(const string& callsign, PluginHost::IShell* entry, Core::hresult (PluginHost::IPlugin::INotification::*notificatonmethod)(const string& callsign, IShell* plugin))
void Notify(const string& callsign, PluginHost::IShell* entry, Core::hresult (NOTIFICATION::*notificatonmethod)(const string& callsign, IShell* plugin))
{
_notificationLock.Lock();

Expand All @@ -2773,7 +2775,7 @@ namespace PluginHost {
if (it->second.SendNotification(callsign, entry) == true) {
Core::hresult result = (it->first->*notificatonmethod)(callsign, entry);
if (result == Core::ERROR_CANCEL) {
PluginHost::IPlugin::INotification* foundnotification = it->first;
NOTIFICATION* foundnotification = it->first;
it = _notifiers.erase(it);
foundnotification->Release();
foundnotification = nullptr;
Expand All @@ -2794,7 +2796,7 @@ namespace PluginHost {

for (const auto& notifier : _notifiers) {
if (notifier.second.SendNotification(callsign, entry) == true) {
PluginHost::IPlugin::ILifeTime* lifeTime = notifier.first->QueryInterface<PluginHost::IPlugin::ILifeTime>();
PluginHost::IPlugin::ILifeTime* lifeTime = notifier.first->template QueryInterface<PluginHost::IPlugin::ILifeTime>();
if (lifeTime != nullptr) {
(lifeTime->*notificatonmethod)(callsign, entry);
lifeTime->Release();
Expand All @@ -2819,7 +2821,7 @@ namespace PluginHost {

private:
template <typename... Args>
bool RegistrationAllowed(PluginHost::IPlugin::INotification* notification, Args&&... args) const
bool RegistrationAllowed(NOTIFICATION* notification, Args&&... args) const
{
bool notallowed = false;
auto range = _notifiers.equal_range(notification);
Expand All @@ -2833,11 +2835,10 @@ namespace PluginHost {
}

private:
std::unordered_multimap<PluginHost::IPlugin::INotification*, Notifier> _notifiers;
std::unordered_multimap<NOTIFICATION*, Notifier> _notifiers;
mutable Core::CriticalSection _notificationLock;
};


using Plugins = std::unordered_map<string, Core::ProxyType<Service>>;
using RemoteInstantiators = std::unordered_map<string, IRemoteInstantiation*>;
using ShellNotifiers = std::vector<Exchange::Controller::IShells::INotification*>;
Expand Down Expand Up @@ -3689,6 +3690,7 @@ namespace PluginHost {
, _notificationLock()
, _services()
, _notifiers()
, _extendedNotifiers()
, _engine(Core::ProxyType<RPC::InvokeServer>::Create(&(server._dispatcher)))
, _processAdministrator(
*this,
Expand Down Expand Up @@ -3816,6 +3818,14 @@ namespace PluginHost {
{
_notifiers.Notify(callsign, entry, &PluginHost::IPlugin::INotification::CancelableUnavailable);
}
void Hibernated(const string& callsign, PluginHost::IShell* entry)
{
_extendedNotifiers.Notify(callsign, entry, &PluginHost::IPlugin::INotificationExtended::CancelableHibernated);
}
void Destroyed(const string& callsign, PluginHost::IShell* entry)
{
_extendedNotifiers.Notify(callsign, entry, &PluginHost::IPlugin::INotificationExtended::CancelableDestroyed);
}
void StateControlStateChange(const string& callsign, const IStateControl::state state)
{
_server.StateControlStateChange(callsign, state);
Expand Down Expand Up @@ -3856,6 +3866,15 @@ namespace PluginHost {
}
}
}
void Register(PluginHost::IPlugin::INotificationExtended* sink, const Core::OptionalType<string>& callsign = {})
{
if (callsign.IsSet() == true) {
_extendedNotifiers.Add(sink, callsign.Value());
}
else {
_extendedNotifiers.Add(sink);
}
}
void Unregister(const PluginHost::IPlugin::INotification* sink, const Core::OptionalType<string>& callsign = {})
{
if (callsign.IsSet() == true) {
Expand All @@ -3864,6 +3883,14 @@ namespace PluginHost {
_notifiers.Remove(sink);
}
}
void Unregister(const PluginHost::IPlugin::INotificationExtended* sink, const Core::OptionalType<string>& callsign = {})
{
if (callsign.IsSet() == true) {
_extendedNotifiers.Remove(sink, callsign.Value());
} else {
_extendedNotifiers.Remove(sink);
}
}
void Register(IPlugin::INotification* sink, const uint32_t interface_id)
{
if( _notifiers.Add(sink, interface_id) == true) {
Expand All @@ -3876,6 +3903,14 @@ namespace PluginHost {
{
_notifiers.Remove(sink, interface_id);
}
void Register(IPlugin::INotificationExtended* sink, const uint32_t interface_id)
{
_extendedNotifiers.Add(sink, interface_id);
}
void Unregister(IPlugin::INotificationExtended* sink, const uint32_t interface_id)
{
_extendedNotifiers.Remove(sink, interface_id);
}
inline void* QueryInterfaceByCallsign(const uint32_t id, const string& name)
{
void* result = nullptr;
Expand Down Expand Up @@ -4305,6 +4340,9 @@ namespace PluginHost {
if (interfaceId == PluginHost::IPlugin::INotification::ID) {
_notifiers.RemoveAll(remote);
}
else if (interfaceId == PluginHost::IPlugin::INotificationExtended::ID) {
_extendedNotifiers.RemoveAll(remote);
}
else if (interfaceId == IShell::IConnectionServer::INotification::ID) {

_notificationLock.Lock();
Expand Down Expand Up @@ -4451,7 +4489,8 @@ namespace PluginHost {
Core::CriticalSection _notificationLock;
Plugins _services;
mutable RemoteInstantiators _instantiators;
Notifiers _notifiers;
Notifiers<PluginHost::IPlugin::INotification> _notifiers;
Notifiers<PluginHost::IPlugin::INotificationExtended> _extendedNotifiers;
Core::ProxyType<RPC::InvokeServer> _engine;
CommunicatorServer _processAdministrator;
Core::SinkType<SubSystems> _subSystems;
Expand Down
1 change: 1 addition & 0 deletions Source/com/Ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ namespace RPC {
ID_COMPOSIT_PLUGIN = (ID_OFFSET_INTERNAL + 0x003B),
ID_COMPOSIT_PLUGIN_CALLBACK = (ID_OFFSET_INTERNAL + 0x003C),
ID_DISPATCHER_CALLBACK = (ID_OFFSET_INTERNAL + 0x003D),
ID_PLUGIN_NOTIFICATION_EXTENDED = (ID_OFFSET_INTERNAL + 0x003E),

ID_SHELL = (ID_OFFSET_INTERNAL + 0x0040),
ID_SHELL_COMLINK = (ID_OFFSET_INTERNAL + 0x0041),
Expand Down
34 changes: 34 additions & 0 deletions Source/plugins/IPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,40 @@ namespace PluginHost {

};

struct INotificationExtended : virtual public Core::IUnknown {

enum { ID = RPC::ID_PLUGIN_NOTIFICATION_EXTENDED };

~INotificationExtended() override = default;

//! @{
//! ================================== CALLED ON THREADPOOL THREAD =====================================
//! Whenever a plugin transitions to a hibernated or destroyed state, this is reported to an observer.
//! @}

// @stubgen:omit
virtual void Hibernated(const string&, IShell*)
{
ASSERT(false);
}
// @stubgen:omit
virtual void Destroyed(const string&, IShell*)
{
ASSERT(false);
}

virtual Core::hresult CancelableHibernated(const string& callsign, IShell* plugin)
{
Hibernated(callsign, plugin);
return Core::ERROR_NONE;
}
virtual Core::hresult CancelableDestroyed(const string& callsign, IShell* plugin)
{
Destroyed(callsign, plugin);
return Core::ERROR_NONE;
}
};

struct ILifeTime : virtual public Core::IUnknown {

enum { ID = RPC::ID_PLUGIN_LIFETIME };
Expand Down
Loading