/*! \brief Checks whether the (pre-)registered applications are still running. This is necessary, since killed applications don't unregister properly. */ void TRoster::CheckSanity() { BAutolock _(fLock); // not early (pre-)registered applications AppInfoList obsoleteApps; for (AppInfoList::Iterator it = fRegisteredApps.It(); it.IsValid(); ++it) { if (!(*it)->IsRunning()) obsoleteApps.AddInfo(*it); } // remove the apps for (AppInfoList::Iterator it = obsoleteApps.It(); it.IsValid(); ++it) { RemoveApp(*it); delete *it; } obsoleteApps.MakeEmpty(false); // don't delete infos a second time // early pre-registered applications bigtime_t timeLimit = system_time() - kMaximalEarlyPreRegistrationPeriod; for (AppInfoList::Iterator it = fEarlyPreRegisteredApps.It(); it.IsValid(); ++it) { if ((*it)->registration_time < timeLimit) obsoleteApps.AddInfo(*it); } // remove the apps for (AppInfoList::Iterator it = obsoleteApps.It(); it.IsValid(); ++it) { fEarlyPreRegisteredApps.RemoveInfo(*it); delete *it; } obsoleteApps.MakeEmpty(false); // don't delete infos a second time }
void ShutdownProcess::_AddShutdownWindowApps(AppInfoList& infos) { if (!fHasGUI) return; for (AppInfoList::Iterator it = infos.It(); it.IsValid(); ++it) { RosterAppInfo* info = *it; // init an app file info BFile file; status_t error = file.SetTo(&info->ref, B_READ_ONLY); if (error != B_OK) { WARNING(("ShutdownProcess::_AddShutdownWindowApps(): Failed to " "open file for app %s: %s\n", info->signature, strerror(error))); continue; } BAppFileInfo appFileInfo; error = appFileInfo.SetTo(&file); if (error != B_OK) { WARNING(("ShutdownProcess::_AddShutdownWindowApps(): Failed to " "init app file info for app %s: %s\n", info->signature, strerror(error))); } // get the application icons #ifdef __HAIKU__ color_space format = B_RGBA32; #else color_space format = B_CMAP8; #endif // mini icon BBitmap* miniIcon = new(nothrow) BBitmap(BRect(0, 0, 15, 15), format); if (miniIcon != NULL) { error = miniIcon->InitCheck(); if (error == B_OK) error = appFileInfo.GetTrackerIcon(miniIcon, B_MINI_ICON); if (error != B_OK) { delete miniIcon; miniIcon = NULL; } } // mini icon BBitmap* largeIcon = new(nothrow) BBitmap(BRect(0, 0, 31, 31), format); if (largeIcon != NULL) { error = largeIcon->InitCheck(); if (error == B_OK) error = appFileInfo.GetTrackerIcon(largeIcon, B_LARGE_ICON); if (error != B_OK) { delete largeIcon; largeIcon = NULL; } } // add the app error = fWindow->AddApp(info->team, miniIcon, largeIcon); if (error != B_OK) { WARNING(("ShutdownProcess::_AddShutdownWindowApps(): Failed to " "add app to the shutdown window: %s\n", strerror(error))); } } }
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; } } } } }