/*! \brief Checks all registered apps for \a ref and \a signature if they are still alive, and removes those that aren't. */ void TRoster::_ValidateRunning(const entry_ref& ref, const char* signature) { while (true) { // get info via ref or signature RosterAppInfo* info = fRegisteredApps.InfoFor(&ref); if (info == NULL && signature != NULL) info = fRegisteredApps.InfoFor(signature); // if app is alive or does not exist, we can exit if (info == NULL || info->IsRunning()) return; RemoveApp(info); delete info; } }
void ShutdownProcess::_QuitApps(AppInfoList& list, bool systemApps) { PRINT(("ShutdownProcess::_QuitApps(%s)\n", (systemApps ? "system" : "user"))); if (systemApps) { _SetShutdownWindowCancelButtonEnabled(false); // check one last time for abort events uint32 event; do { team_id team; int32 phase; status_t error = _GetNextEvent(event, team, phase, false); if (error != B_OK) throw_error(error); if (event == ABORT_EVENT) { PRINT(("ShutdownProcess::_QuitApps(): shutdown cancelled by " "team %ld (-1 => user)\n", team)); _DisplayAbortingApp(team); throw_error(B_SHUTDOWN_CANCELLED); } } while (event != NO_EVENT); } // prepare the shutdown message BMessage message; _PrepareShutdownMessage(message); // now iterate through the list of apps while (true) { // eat events uint32 event; do { team_id team; int32 phase; status_t error = _GetNextEvent(event, team, phase, false); if (error != B_OK) throw_error(error); if (!systemApps && event == ABORT_EVENT) { PRINT(("ShutdownProcess::_QuitApps(): shutdown cancelled by " "team %ld (-1 => user)\n", team)); _DisplayAbortingApp(team); throw_error(B_SHUTDOWN_CANCELLED); } } while (event != NO_EVENT); // get the first app to quit team_id team = -1; port_id port = -1; char appName[B_FILE_NAME_LENGTH]; { BAutolock _(fWorkerLock); while (!list.IsEmpty()) { RosterAppInfo* info = *list.It(); team = info->team; port = info->port; strcpy(appName, info->ref.name); if (info->IsRunning()) break; list.RemoveInfo(info); delete info; } } if (team < 0) { PRINT(("ShutdownProcess::_QuitApps() done\n")); return; } // set window text BString buffer = B_TRANSLATE("Asking \"%appName%\" to quit."); buffer.ReplaceFirst("%appName%", appName); _SetShutdownWindowText(buffer.String()); _SetShutdownWindowCurrentApp(team); // send the shutdown message to the app PRINT((" sending team %ld (port: %ld) a shutdown message\n", team, port)); SingleMessagingTargetSet target(port, B_PREFERRED_TOKEN); MessageDeliverer::Default()->DeliverMessage(&message, target); // schedule a timeout event _ScheduleTimeoutEvent(kAppQuitTimeout, team); // wait for the app to die or for the timeout to occur bool appGone = _WaitForApp(team, &list, systemApps); if (appGone) { // fine: the app finished in an orderly manner } else { // the app is either blocking on a model alert or blocks for another // reason if (!systemApps) _QuitBlockingApp(list, team, appName, true); else { // This is a system app: remove it from the list BAutolock _(fWorkerLock); if (RosterAppInfo* info = list.InfoFor(team)) { list.RemoveInfo(info); delete info; } } } } }