From b19b3d9b39d14484e6270c272a2a7ea9ab08d9b4 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 28 Sep 2021 15:49:01 -0400 Subject: [PATCH] launch_daemon: Refactor handling of ExternalEventSources. * Refactor ResolveExternalEvent to actually return the resolved event, not just whether or not one was found, and then skip resolution in TriggerExternalEvent and ResetStickyExternalEvent, which now should only be passed ExternalEvents. * ExternalEventSources now store destination Events, not Jobs, following on that refactor. * The second variant of ResolveExternalEvents is dropped, and instead the Register/Unregister functions are implemented. * Trigger and ResetSticky are now done in ExternalEventSource, which now keeps track of whether it has been sticky-triggered or not, though it does not use this information yet. These changes should not affect behavior, they largely constitute a reorganization (though some TODOs are resolved.) Change-Id: I46a51cac0edb90e90b154ef9c94791cb7a1aad94 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4509 Reviewed-by: waddlesplash --- src/servers/launch/Events.cpp | 65 +++++---------- src/servers/launch/Events.h | 8 +- src/servers/launch/LaunchDaemon.cpp | 120 ++++++++++++++-------------- 3 files changed, 85 insertions(+), 108 deletions(-) diff --git a/src/servers/launch/Events.cpp b/src/servers/launch/Events.cpp index d3d8e37b4e..7d43734290 100644 --- a/src/servers/launch/Events.cpp +++ b/src/servers/launch/Events.cpp @@ -703,74 +703,53 @@ Events::AddOnDemand(const BMessenger& target, Event* event) } -/*static*/ bool +/*static*/ Event* Events::ResolveExternalEvent(Event* event, const char* name, uint32 flags) { if (event == NULL) - return false; + return NULL; if (EventContainer* container = dynamic_cast(event)) { for (int32 index = 0; index < container->Events().CountItems(); index++) { - Event* event = container->Events().ItemAt(index); - if (ExternalEvent* external = dynamic_cast(event)) { - if (external->Name() == name && external->Resolve(flags)) - return true; - } else if (dynamic_cast(event) != NULL) { - if (ResolveExternalEvent(event, name, flags)) - return true; - } + Event* event = ResolveExternalEvent(container->Events().ItemAt(index), name, flags); + if (event != NULL) + return event; } + } else if (ExternalEvent* external = dynamic_cast(event)) { + if (external->Name() == name && external->Resolve(flags)) + return external; } - return false; + + return NULL; } /*static*/ void -Events::TriggerExternalEvent(Event* event, const char* name) +Events::TriggerExternalEvent(Event* event) { if (event == NULL) return; - if (EventContainer* container = dynamic_cast(event)) { - for (int32 index = 0; index < container->Events().CountItems(); - index++) { - Event* event = container->Events().ItemAt(index); - if (ExternalEvent* external = dynamic_cast(event)) { - if (external->Name() == name) { - external->Trigger(container); - return; - } - } else if (dynamic_cast(event) != NULL) { - TriggerExternalEvent(event, name); - } - } - } - return; + ExternalEvent* external = dynamic_cast(event); + if (external == NULL) + return; + + external->Trigger(external); } /*static*/ void -Events::ResetStickyExternalEvent(Event* event, const char* name) +Events::ResetStickyExternalEvent(Event* event) { if (event == NULL) return; - if (EventContainer* container = dynamic_cast(event)) { - for (int32 index = 0; index < container->Events().CountItems(); - index++) { - Event* event = container->Events().ItemAt(index); - if (ExternalEvent* external = dynamic_cast(event)) { - if (external->Name() == name) { - external->ResetSticky(); - return; - } - } else if (dynamic_cast(event) != NULL) { - ResetStickyExternalEvent(event, name); - } - } - } - return; + ExternalEvent* external = dynamic_cast(event); + if (external == NULL) + return; + + external->ResetSticky(); } diff --git a/src/servers/launch/Events.h b/src/servers/launch/Events.h index cf06118f96..3ee4d69f85 100644 --- a/src/servers/launch/Events.h +++ b/src/servers/launch/Events.h @@ -56,12 +56,10 @@ public: static Event* FromMessage(const BMessenger& target, const BMessage& message); static Event* AddOnDemand(const BMessenger& target, Event* event); - static bool ResolveExternalEvent(Event* event, + static Event* ResolveExternalEvent(Event* event, const char* name, uint32 flags); - static void TriggerExternalEvent(Event* event, - const char* name); - static void ResetStickyExternalEvent(Event* event, - const char* name); + static void TriggerExternalEvent(Event* event); + static void ResetStickyExternalEvent(Event* event); static bool TriggerDemand(Event* event, bool testOnly = false); }; diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index 411f09a771..cc357d0404 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -105,16 +105,17 @@ public: uint32 Flags() const { return fFlags; } - int32 CountListeners() const; - BaseJob* ListenerAt(int32 index) const; + void Trigger(); + void ResetSticky(); - status_t AddListener(BaseJob* job); - void RemoveListener(BaseJob* job); + status_t AddDestination(Event* event); + void RemoveDestination(Event* event); private: BString fName; uint32 fFlags; - BObjectList fListeners; + BObjectList fDestinations; + bool fStickyTriggered; }; @@ -206,12 +207,11 @@ private: const BMessage& message); ExternalEventSource* - _FindEvent(const char* owner, + _FindExternalEventSource(const char* owner, const char* name) const; void _ResolveExternalEvents( ExternalEventSource* event, const BString& name); - void _ResolveExternalEvents(BaseJob* job); void _GetBaseJobInfo(BaseJob* job, BMessage& info); void _ForwardEventMessage(uid_t user, BMessage* message); @@ -274,7 +274,8 @@ ExternalEventSource::ExternalEventSource(BMessenger& source, : fName(name), fFlags(flags), - fListeners(5, true) + fDestinations(5), + fStickyTriggered(false) { } @@ -291,24 +292,32 @@ ExternalEventSource::Name() const } -int32 -ExternalEventSource::CountListeners() const +void +ExternalEventSource::Trigger() { - return fListeners.CountItems(); + for (int32 index = 0; index < fDestinations.CountItems(); index++) + Events::TriggerExternalEvent(fDestinations.ItemAt(index)); + + if ((fFlags & B_STICKY_EVENT) != 0) + fStickyTriggered = true; } -BaseJob* -ExternalEventSource::ListenerAt(int32 index) const +void +ExternalEventSource::ResetSticky() { - return fListeners.ItemAt(index); + if ((fFlags & B_STICKY_EVENT) != 0) + fStickyTriggered = false; + + for (int32 index = 0; index < fDestinations.CountItems(); index++) + Events::ResetStickyExternalEvent(fDestinations.ItemAt(index)); } status_t -ExternalEventSource::AddListener(BaseJob* job) +ExternalEventSource::AddDestination(Event* event) { - if (fListeners.AddItem(job)) + if (fDestinations.AddItem(event)) return B_OK; return B_NO_MEMORY; @@ -316,9 +325,9 @@ ExternalEventSource::AddListener(BaseJob* job) void -ExternalEventSource::RemoveListener(BaseJob* job) +ExternalEventSource::RemoveDestination(Event* event) { - fListeners.RemoveItem(job); + fDestinations.RemoveItem(event); } @@ -415,15 +424,34 @@ status_t LaunchDaemon::RegisterExternalEvent(Event* event, const char* name, const BStringList& arguments) { - // TODO: register actual event with event source - return B_OK; + status_t status = B_NAME_NOT_FOUND; + for (EventMap::iterator iterator = fEvents.begin(); + iterator != fEvents.end(); iterator++) { + ExternalEventSource* eventSource = iterator->second; + Event* externalEvent = Events::ResolveExternalEvent(event, + eventSource->Name(), eventSource->Flags()); + if (externalEvent != NULL) { + status = eventSource->AddDestination(event); + break; + } + } + return status; } void LaunchDaemon::UnregisterExternalEvent(Event* event, const char* name) { - // TODO! + for (EventMap::iterator iterator = fEvents.begin(); + iterator != fEvents.end(); iterator++) { + ExternalEventSource* eventSource = iterator->second; + Event* externalEvent = Events::ResolveExternalEvent(event, + eventSource->Name(), eventSource->Flags()); + if (externalEvent != NULL) { + eventSource->RemoveDestination(event); + break; + } + } } @@ -1059,16 +1087,10 @@ LaunchDaemon::_HandleNotifyLaunchEvent(BMessage* message) const char* ownerName = message->GetString("owner"); // TODO: support arguments (as selectors) - ExternalEventSource* event = _FindEvent(ownerName, name); + ExternalEventSource* event = _FindExternalEventSource(ownerName, name); if (event != NULL) { fLog.ExternalEventTriggered(name); - - // Evaluate all of its jobs - int32 count = event->CountListeners(); - for (int32 index = 0; index < count; index++) { - BaseJob* listener = event->ListenerAt(index); - Events::TriggerExternalEvent(listener->Event(), name); - } + event->Trigger(); } } @@ -1089,15 +1111,9 @@ LaunchDaemon::_HandleResetStickyLaunchEvent(BMessage* message) const char* ownerName = message->GetString("owner"); // TODO: support arguments (as selectors) - ExternalEventSource* event = _FindEvent(ownerName, name); - if (event != NULL) { - // Evaluate all of its jobs - int32 count = event->CountListeners(); - for (int32 index = 0; index < count; index++) { - BaseJob* listener = event->ListenerAt(index); - Events::ResetStickyExternalEvent(listener->Event(), name); - } - } + ExternalEventSource* eventSource = _FindExternalEventSource(ownerName, name); + if (eventSource != NULL) + eventSource->ResetSticky(); } _ForwardEventMessage(user, message); @@ -1844,7 +1860,6 @@ LaunchDaemon::_SetEvent(BaseJob* job, const BMessage& message) if (updated) { TRACE(" event: %s\n", event->ToString().String()); job->SetEvent(event); - _ResolveExternalEvents(job); } } @@ -1859,7 +1874,7 @@ LaunchDaemon::_SetEnvironment(BaseJob* job, const BMessage& message) ExternalEventSource* -LaunchDaemon::_FindEvent(const char* owner, const char* name) const +LaunchDaemon::_FindExternalEventSource(const char* owner, const char* name) const { if (name == NULL) return NULL; @@ -1886,30 +1901,15 @@ LaunchDaemon::_FindEvent(const char* owner, const char* name) const void -LaunchDaemon::_ResolveExternalEvents(ExternalEventSource* event, +LaunchDaemon::_ResolveExternalEvents(ExternalEventSource* eventSource, const BString& name) { for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end(); iterator++) { - Job* job = iterator->second; - if (Events::ResolveExternalEvent(job->Event(), name, event->Flags())) - event->AddListener(job); - } -} - - -void -LaunchDaemon::_ResolveExternalEvents(BaseJob* job) -{ - if (job->Event() == NULL) - return; - - for (EventMap::iterator iterator = fEvents.begin(); - iterator != fEvents.end(); iterator++) { - ExternalEventSource* event = iterator->second; - if (Events::ResolveExternalEvent(job->Event(), event->Name(), - event->Flags())) - event->AddListener(job); + Event* externalEvent = Events::ResolveExternalEvent(iterator->second->Event(), + name, eventSource->Flags()); + if (externalEvent != NULL) + eventSource->AddDestination(externalEvent); } }