/*! Initializes all jobs for the specified target (may be \c NULL). Jobs that cannot be initialized, and those that never will be due to conditions, will be removed from the list. */ void LaunchDaemon::_InitJobs(Target* target) { for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();) { Job* job = iterator->second; JobMap::iterator remove = iterator++; if (job->Target() != target) continue; status_t status = B_NO_INIT; if (job->IsEnabled()) { // Filter out jobs that have a constant and failing condition if (job->Condition() == NULL || !job->Condition()->IsConstant(*this) || job->Condition()->Test(*this)) { std::set<BString> dependencies; status = job->Init(*this, dependencies); if (status == B_OK && job->Event() != NULL) status = job->Event()->Register(*this); } } if (status != B_OK) { if (status != B_NO_INIT) { // TODO: log error debug_printf("Init \"%s\" failed: %s\n", job->Name(), strerror(status)); } // Remove jobs that won't be used later on fJobs.erase(remove); delete job; } } }
void LaunchDaemon::_HandleGetLaunchData(BMessage* message) { uid_t user = _GetUserID(message); if (user < 0) return; BMessage reply((uint32)B_OK); bool launchJob = true; Job* job = FindJob(get_leaf(message->GetString("name"))); if (job == NULL) { Session* session = FindSession(user); if (session != NULL) { // Forward request to user launch_daemon if (session->Daemon().SendMessage(message) == B_OK) return; } reply.what = B_NAME_NOT_FOUND; } else if (job->IsService() && !job->IsLaunched()) { if (job->InitCheck() == B_NO_INIT || !job->CheckCondition(*this)) { // The job exists, but cannot be started yet, as its // conditions are not met; don't make it available yet // TODO: we may not want to initialize jobs with conditions // that aren't met yet reply.what = B_NO_INIT; } else if (job->Event() != NULL) { if (!Events::TriggerDemand(job->Event())) { // The job is not triggered by demand; we cannot start it now reply.what = B_NO_INIT; } else { // The job has already been triggered, don't launch it again launchJob = false; } } } else launchJob = false; bool ownsMessage = false; if (reply.what == B_OK) { // Launch the job if it hasn't been launched already if (launchJob) _LaunchJob(job, TRIGGER_DEMAND); DetachCurrentMessage(); status_t result = job->HandleGetLaunchData(message); if (result == B_OK) { // Replying is delegated to the job. return; } ownsMessage = true; reply.what = result; } message->SendReply(&reply); if (ownsMessage) delete message; }
void LaunchDaemon::_ResolveExternalEvents(ExternalEventSource* event, 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::_ResolveRegisteredEvents(RegisteredEvent* event, const BString& name) { for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end(); iterator++) { Job* job = iterator->second; if (Events::ResolveRegisteredEvent(job->Event(), name)) event->AddListener(job); } }
void LaunchDaemon::_HandleGetLaunchData(BMessage* message) { uid_t user = _GetUserID(message); if (user < 0) return; BMessage reply((uint32)B_OK); bool launchJob = true; Job* job = FindJob(get_leaf(message->GetString("name"))); if (job == NULL) { Session* session = FindSession(user); if (session != NULL) { // Forward request to user launch_daemon if (session->Daemon().SendMessage(message) == B_OK) return; } reply.what = B_NAME_NOT_FOUND; } else if (!job->IsLaunched()) { if (job->InitCheck() == B_NO_INIT || !job->CheckCondition(*this)) { // The job exists, but cannot be started yet, as its // conditions are not met; don't make it available yet // TODO: we may not want to initialize jobs with conditions // that aren't met yet reply.what = B_NO_INIT; } else if (job->Event() != NULL) { if (!Events::TriggerDemand(job->Event())) { // The job is not triggered by demand; we cannot start it now reply.what = B_NO_INIT; } else { // The job has already been triggered, don't launch it again launchJob = false; } } } if (reply.what == B_OK) { // If the job has not been launched yet, we'll pass on our // team here. The rationale behind this is that this team // will temporarily own the synchronous reply ports. reply.AddInt32("team", job->Team() < 0 ? current_team() : job->Team()); PortMap::const_iterator iterator = job->Ports().begin(); for (; iterator != job->Ports().end(); iterator++) { BString name; if (iterator->second.HasString("name")) name << iterator->second.GetString("name") << "_"; name << "port"; reply.AddInt32(name.String(), iterator->second.GetInt32("port", -1)); } // Launch the job if it hasn't been launched already if (launchJob) _LaunchJob(job); } message->SendReply(&reply); }