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 <[email protected]>
This commit is contained in:
Augustin Cavalier
2021-09-29 15:44:35 +00:00
committed by waddlesplash
parent ffc83aa24a
commit b19b3d9b39
3 changed files with 85 additions and 108 deletions
+22 -43
View File
@@ -703,74 +703,53 @@ Events::AddOnDemand(const BMessenger& target, Event* event)
} }
/*static*/ bool /*static*/ Event*
Events::ResolveExternalEvent(Event* event, const char* name, uint32 flags) Events::ResolveExternalEvent(Event* event, const char* name, uint32 flags)
{ {
if (event == NULL) if (event == NULL)
return false; return NULL;
if (EventContainer* container = dynamic_cast<EventContainer*>(event)) { if (EventContainer* container = dynamic_cast<EventContainer*>(event)) {
for (int32 index = 0; index < container->Events().CountItems(); for (int32 index = 0; index < container->Events().CountItems();
index++) { index++) {
Event* event = container->Events().ItemAt(index); Event* event = ResolveExternalEvent(container->Events().ItemAt(index), name, flags);
if (ExternalEvent* external = dynamic_cast<ExternalEvent*>(event)) { if (event != NULL)
if (external->Name() == name && external->Resolve(flags)) return event;
return true;
} else if (dynamic_cast<EventContainer*>(event) != NULL) {
if (ResolveExternalEvent(event, name, flags))
return true;
}
} }
} else if (ExternalEvent* external = dynamic_cast<ExternalEvent*>(event)) {
if (external->Name() == name && external->Resolve(flags))
return external;
} }
return false;
return NULL;
} }
/*static*/ void /*static*/ void
Events::TriggerExternalEvent(Event* event, const char* name) Events::TriggerExternalEvent(Event* event)
{ {
if (event == NULL) if (event == NULL)
return; return;
if (EventContainer* container = dynamic_cast<EventContainer*>(event)) { ExternalEvent* external = dynamic_cast<ExternalEvent*>(event);
for (int32 index = 0; index < container->Events().CountItems(); if (external == NULL)
index++) { return;
Event* event = container->Events().ItemAt(index);
if (ExternalEvent* external = dynamic_cast<ExternalEvent*>(event)) { external->Trigger(external);
if (external->Name() == name) {
external->Trigger(container);
return;
}
} else if (dynamic_cast<EventContainer*>(event) != NULL) {
TriggerExternalEvent(event, name);
}
}
}
return;
} }
/*static*/ void /*static*/ void
Events::ResetStickyExternalEvent(Event* event, const char* name) Events::ResetStickyExternalEvent(Event* event)
{ {
if (event == NULL) if (event == NULL)
return; return;
if (EventContainer* container = dynamic_cast<EventContainer*>(event)) { ExternalEvent* external = dynamic_cast<ExternalEvent*>(event);
for (int32 index = 0; index < container->Events().CountItems(); if (external == NULL)
index++) { return;
Event* event = container->Events().ItemAt(index);
if (ExternalEvent* external = dynamic_cast<ExternalEvent*>(event)) { external->ResetSticky();
if (external->Name() == name) {
external->ResetSticky();
return;
}
} else if (dynamic_cast<EventContainer*>(event) != NULL) {
ResetStickyExternalEvent(event, name);
}
}
}
return;
} }
+3 -5
View File
@@ -56,12 +56,10 @@ public:
static Event* FromMessage(const BMessenger& target, static Event* FromMessage(const BMessenger& target,
const BMessage& message); const BMessage& message);
static Event* AddOnDemand(const BMessenger& target, Event* event); static Event* AddOnDemand(const BMessenger& target, Event* event);
static bool ResolveExternalEvent(Event* event, static Event* ResolveExternalEvent(Event* event,
const char* name, uint32 flags); const char* name, uint32 flags);
static void TriggerExternalEvent(Event* event, static void TriggerExternalEvent(Event* event);
const char* name); static void ResetStickyExternalEvent(Event* event);
static void ResetStickyExternalEvent(Event* event,
const char* name);
static bool TriggerDemand(Event* event, bool testOnly = false); static bool TriggerDemand(Event* event, bool testOnly = false);
}; };
+60 -60
View File
@@ -105,16 +105,17 @@ public:
uint32 Flags() const uint32 Flags() const
{ return fFlags; } { return fFlags; }
int32 CountListeners() const; void Trigger();
BaseJob* ListenerAt(int32 index) const; void ResetSticky();
status_t AddListener(BaseJob* job); status_t AddDestination(Event* event);
void RemoveListener(BaseJob* job); void RemoveDestination(Event* event);
private: private:
BString fName; BString fName;
uint32 fFlags; uint32 fFlags;
BObjectList<BaseJob> fListeners; BObjectList<Event> fDestinations;
bool fStickyTriggered;
}; };
@@ -206,12 +207,11 @@ private:
const BMessage& message); const BMessage& message);
ExternalEventSource* ExternalEventSource*
_FindEvent(const char* owner, _FindExternalEventSource(const char* owner,
const char* name) const; const char* name) const;
void _ResolveExternalEvents( void _ResolveExternalEvents(
ExternalEventSource* event, ExternalEventSource* event,
const BString& name); const BString& name);
void _ResolveExternalEvents(BaseJob* job);
void _GetBaseJobInfo(BaseJob* job, BMessage& info); void _GetBaseJobInfo(BaseJob* job, BMessage& info);
void _ForwardEventMessage(uid_t user, void _ForwardEventMessage(uid_t user,
BMessage* message); BMessage* message);
@@ -274,7 +274,8 @@ ExternalEventSource::ExternalEventSource(BMessenger& source,
: :
fName(name), fName(name),
fFlags(flags), fFlags(flags),
fListeners(5, true) fDestinations(5),
fStickyTriggered(false)
{ {
} }
@@ -291,24 +292,32 @@ ExternalEventSource::Name() const
} }
int32 void
ExternalEventSource::CountListeners() const 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* void
ExternalEventSource::ListenerAt(int32 index) const 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 status_t
ExternalEventSource::AddListener(BaseJob* job) ExternalEventSource::AddDestination(Event* event)
{ {
if (fListeners.AddItem(job)) if (fDestinations.AddItem(event))
return B_OK; return B_OK;
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -316,9 +325,9 @@ ExternalEventSource::AddListener(BaseJob* job)
void 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, LaunchDaemon::RegisterExternalEvent(Event* event, const char* name,
const BStringList& arguments) const BStringList& arguments)
{ {
// TODO: register actual event with event source status_t status = B_NAME_NOT_FOUND;
return B_OK; 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 void
LaunchDaemon::UnregisterExternalEvent(Event* event, const char* name) 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"); const char* ownerName = message->GetString("owner");
// TODO: support arguments (as selectors) // TODO: support arguments (as selectors)
ExternalEventSource* event = _FindEvent(ownerName, name); ExternalEventSource* event = _FindExternalEventSource(ownerName, name);
if (event != NULL) { if (event != NULL) {
fLog.ExternalEventTriggered(name); fLog.ExternalEventTriggered(name);
event->Trigger();
// 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);
}
} }
} }
@@ -1089,15 +1111,9 @@ LaunchDaemon::_HandleResetStickyLaunchEvent(BMessage* message)
const char* ownerName = message->GetString("owner"); const char* ownerName = message->GetString("owner");
// TODO: support arguments (as selectors) // TODO: support arguments (as selectors)
ExternalEventSource* event = _FindEvent(ownerName, name); ExternalEventSource* eventSource = _FindExternalEventSource(ownerName, name);
if (event != NULL) { if (eventSource != NULL)
// Evaluate all of its jobs eventSource->ResetSticky();
int32 count = event->CountListeners();
for (int32 index = 0; index < count; index++) {
BaseJob* listener = event->ListenerAt(index);
Events::ResetStickyExternalEvent(listener->Event(), name);
}
}
} }
_ForwardEventMessage(user, message); _ForwardEventMessage(user, message);
@@ -1844,7 +1860,6 @@ LaunchDaemon::_SetEvent(BaseJob* job, const BMessage& message)
if (updated) { if (updated) {
TRACE(" event: %s\n", event->ToString().String()); TRACE(" event: %s\n", event->ToString().String());
job->SetEvent(event); job->SetEvent(event);
_ResolveExternalEvents(job);
} }
} }
@@ -1859,7 +1874,7 @@ LaunchDaemon::_SetEnvironment(BaseJob* job, const BMessage& message)
ExternalEventSource* ExternalEventSource*
LaunchDaemon::_FindEvent(const char* owner, const char* name) const LaunchDaemon::_FindExternalEventSource(const char* owner, const char* name) const
{ {
if (name == NULL) if (name == NULL)
return NULL; return NULL;
@@ -1886,30 +1901,15 @@ LaunchDaemon::_FindEvent(const char* owner, const char* name) const
void void
LaunchDaemon::_ResolveExternalEvents(ExternalEventSource* event, LaunchDaemon::_ResolveExternalEvents(ExternalEventSource* eventSource,
const BString& name) const BString& name)
{ {
for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end(); for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();
iterator++) { iterator++) {
Job* job = iterator->second; Event* externalEvent = Events::ResolveExternalEvent(iterator->second->Event(),
if (Events::ResolveExternalEvent(job->Event(), name, event->Flags())) name, eventSource->Flags());
event->AddListener(job); if (externalEvent != NULL)
} eventSource->AddDestination(externalEvent);
}
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);
} }
} }