BLaunchRoster::ResetStickyEvent() added.

* Used to unflag sticky events that already have been triggered once.
This commit is contained in:
Axel Dörfler 2015-10-21 21:17:41 +02:00
parent 0507a7886a
commit 2e17b6504f
7 changed files with 99 additions and 4 deletions

View File

@ -257,4 +257,23 @@ on {
*/
/*!
\fn status_t BLaunchRoster::ResetStickyEvent(const BMessenger& source,
const char* name);
\brief Resets a previously triggered sticky event.
When an event triggered that is marked as \c B_STICKY_EVENT, its status
will be reset when you call this method for it.
You must have previously registered the event, in order to make the
launch_daemon do anything. Unknown event notifications will be ignored.
\param source The messenger the event is coming from.
\param name The name of the event.
\return B_OK if the event could be reset, otherwise an error code.
\since Haiku R1
*/
//! @}

View File

@ -31,6 +31,7 @@ enum {
B_REGISTER_LAUNCH_EVENT = 'lnre',
B_UNREGISTER_LAUNCH_EVENT = 'lnue',
B_NOTIFY_LAUNCH_EVENT = 'lnne',
B_RESET_STICKY_LAUNCH_EVENT = 'lnRe',
};

View File

@ -42,6 +42,8 @@ public:
const char* name);
status_t NotifyEvent(const BMessenger& source,
const char* name);
status_t ResetStickyEvent(const BMessenger& source,
const char* name);
class Private;

View File

@ -227,6 +227,13 @@ BLaunchRoster::NotifyEvent(const BMessenger& source, const char* name)
}
status_t
BLaunchRoster::ResetStickyEvent(const BMessenger& source, const char* name)
{
return _UpdateEvent(B_RESET_STICKY_LAUNCH_EVENT, source, name);
}
void
BLaunchRoster::_InitMessenger()
{

View File

@ -86,6 +86,7 @@ public:
const BString& Name() const;
bool Resolve(uint32 flags);
void ResetSticky();
virtual void ResetTrigger();
virtual status_t Register(EventRegistrator& registrator);
@ -457,12 +458,18 @@ ExternalEvent::Resolve(uint32 flags)
void
ExternalEvent::ResetTrigger()
ExternalEvent::ResetSticky()
{
if ((fFlags & B_STICKY_EVENT) != 0)
return;
Event::ResetTrigger();
}
Event::ResetTrigger();
void
ExternalEvent::ResetTrigger()
{
if ((fFlags & B_STICKY_EVENT) == 0)
Event::ResetTrigger();
}
@ -642,6 +649,30 @@ Events::TriggerExternalEvent(Event* event, const char* name)
}
/*static*/ void
Events::ResetStickyExternalEvent(Event* event, const char* name)
{
if (event == NULL)
return;
if (EventContainer* container = dynamic_cast<EventContainer*>(event)) {
for (int32 index = 0; index < container->Events().CountItems();
index++) {
Event* event = container->Events().ItemAt(index);
if (ExternalEvent* external = dynamic_cast<ExternalEvent*>(event)) {
if (external->Name() == name) {
external->ResetSticky();
return;
}
} else if (dynamic_cast<EventContainer*>(event) != NULL) {
ResetStickyExternalEvent(event, name);
}
}
}
return;
}
/*! This will trigger a demand event, if it exists.
\return \c true, if there is a demand event, and it has been

View File

@ -60,6 +60,8 @@ public:
const char* name, uint32 flags);
static void TriggerExternalEvent(Event* event,
const char* name);
static void ResetStickyExternalEvent(Event* event,
const char* name);
static bool TriggerDemand(Event* event);
};

View File

@ -144,7 +144,8 @@ private:
void _HandleRegisterLaunchEvent(BMessage* message);
void _HandleUnregisterLaunchEvent(BMessage* message);
void _HandleNotifyLaunchEvent(BMessage* message);
void _HandleResetStickyLaunchEvent(
BMessage* message);
uid_t _GetUserID(BMessage* message);
void _ReadPaths(const BStringList& paths);
@ -463,6 +464,10 @@ LaunchDaemon::MessageReceived(BMessage* message)
_HandleNotifyLaunchEvent(message);
break;
case B_RESET_STICKY_LAUNCH_EVENT:
_HandleResetStickyLaunchEvent(message);
break;
case kMsgEventTriggered:
{
// An internal event has been triggered.
@ -762,6 +767,34 @@ LaunchDaemon::_HandleNotifyLaunchEvent(BMessage* message)
}
void
LaunchDaemon::_HandleResetStickyLaunchEvent(BMessage* message)
{
uid_t user = _GetUserID(message);
if (user < 0)
return;
if (user == 0 || fUserMode) {
// Reset sticky events
const char* name = message->GetString("name");
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);
}
}
}
_ForwardEventMessage(user, message);
}
uid_t
LaunchDaemon::_GetUserID(BMessage* message)
{