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); } }