bonefish+axeld:
* The debug_server now sends the registrar messages whenever the debug alert is shown, and also, if the user wants to debug the team. * In the latter case, the registrar will now cancel a shutdown process. * Also, it will now wait with the shutdown process until the user has acknowledged the debugger alert. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22926 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -104,6 +104,9 @@ enum {
|
|||||||
B_REG_UPDATE_DISK_DEVICE = 'rgud',
|
B_REG_UPDATE_DISK_DEVICE = 'rgud',
|
||||||
B_REG_DEVICE_START_WATCHING = 'rgwd',
|
B_REG_DEVICE_START_WATCHING = 'rgwd',
|
||||||
B_REG_DEVICE_STOP_WATCHING = 'rgsd',
|
B_REG_DEVICE_STOP_WATCHING = 'rgsd',
|
||||||
|
|
||||||
|
// debug_server notifications
|
||||||
|
B_REG_TEAM_DEBUGGER_ALERT = 'rtda',
|
||||||
};
|
};
|
||||||
|
|
||||||
// B_REG_MIME_SET_PARAM "which" constants
|
// B_REG_MIME_SET_PARAM "which" constants
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <Invoker.h>
|
#include <Invoker.h>
|
||||||
|
|
||||||
|
#include <RegistrarDefs.h>
|
||||||
#include <RosterPrivate.h>
|
#include <RosterPrivate.h>
|
||||||
#include <Server.h>
|
#include <Server.h>
|
||||||
|
|
||||||
@@ -115,6 +116,7 @@ private:
|
|||||||
const void *address, char *buffer, int32 bufferSize);
|
const void *address, char *buffer, int32 bufferSize);
|
||||||
void _PrintStackTrace(thread_id thread);
|
void _PrintStackTrace(thread_id thread);
|
||||||
void _NotifyAppServer(team_id team);
|
void _NotifyAppServer(team_id team);
|
||||||
|
void _NotifyRegistrar(team_id team, bool openAlert, bool stopShutdown);
|
||||||
|
|
||||||
status_t _InitGUI();
|
status_t _InitGUI();
|
||||||
|
|
||||||
@@ -258,8 +260,7 @@ TeamDebugHandlerRoster *TeamDebugHandlerRoster::sRoster = NULL;
|
|||||||
|
|
||||||
|
|
||||||
// DebugServer
|
// DebugServer
|
||||||
class DebugServer : public BServer
|
class DebugServer : public BServer {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
DebugServer(status_t &error);
|
DebugServer(status_t &error);
|
||||||
|
|
||||||
@@ -558,16 +559,20 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message)
|
|||||||
} else if (USE_GUI && _AreGUIServersAlive() && _InitGUI() == B_OK) {
|
} else if (USE_GUI && _AreGUIServersAlive() && _InitGUI() == B_OK) {
|
||||||
// normal app -- tell the user
|
// normal app -- tell the user
|
||||||
_NotifyAppServer(fTeam);
|
_NotifyAppServer(fTeam);
|
||||||
|
_NotifyRegistrar(fTeam, true, false);
|
||||||
|
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
snprintf(buffer, sizeof(buffer), "The application:\n\n %s\n\n"
|
snprintf(buffer, sizeof(buffer), "The application:\n\n %s\n\n"
|
||||||
"has encountered an error which prevents it from continuing. Haiku "
|
"has encountered an error which prevents it from continuing. Haiku "
|
||||||
"will terminate the application and clean up.", fTeamInfo.args);
|
"will terminate the application and clean up.", fTeamInfo.args);
|
||||||
|
|
||||||
|
// TODO: It would be nice if the alert would go away automatically
|
||||||
|
// if someone else kills our teams.
|
||||||
BAlert *alert = new BAlert(NULL, buffer, "Debug", "OK", NULL,
|
BAlert *alert = new BAlert(NULL, buffer, "Debug", "OK", NULL,
|
||||||
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||||
int32 result = alert->Go();
|
int32 result = alert->Go();
|
||||||
kill = (result == 1);
|
kill = (result == 1);
|
||||||
|
_NotifyRegistrar(fTeam, false, !kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
return kill;
|
return kill;
|
||||||
@@ -688,6 +693,22 @@ TeamDebugHandler::_NotifyAppServer(team_id team)
|
|||||||
roster.ApplicationCrashed(team);
|
roster.ApplicationCrashed(team);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamDebugHandler::_NotifyRegistrar(team_id team, bool openAlert,
|
||||||
|
bool stopShutdown)
|
||||||
|
{
|
||||||
|
BMessage notify(BPrivate::B_REG_TEAM_DEBUGGER_ALERT);
|
||||||
|
notify.AddInt32("team", team);
|
||||||
|
notify.AddBool("open", openAlert);
|
||||||
|
notify.AddBool("stop shutdown", stopShutdown);
|
||||||
|
|
||||||
|
BRoster::Private roster;
|
||||||
|
BMessage reply;
|
||||||
|
roster.SendTo(¬ify, &reply, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// _InitGUI
|
// _InitGUI
|
||||||
status_t
|
status_t
|
||||||
TeamDebugHandler::_InitGUI()
|
TeamDebugHandler::_InitGUI()
|
||||||
@@ -895,7 +916,7 @@ DebugServer::Init()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuitRequested
|
|
||||||
bool
|
bool
|
||||||
DebugServer::QuitRequested()
|
DebugServer::QuitRequested()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ Registrar::_MessageReceived(BMessage *message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shutdown process
|
||||||
case B_REG_SHUT_DOWN:
|
case B_REG_SHUT_DOWN:
|
||||||
{
|
{
|
||||||
PRINT(("B_REG_SHUT_DOWN\n"));
|
PRINT(("B_REG_SHUT_DOWN\n"));
|
||||||
@@ -229,6 +230,12 @@ Registrar::_MessageReceived(BMessage *message)
|
|||||||
_HandleShutDown(message);
|
_HandleShutDown(message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case B_REG_TEAM_DEBUGGER_ALERT:
|
||||||
|
{
|
||||||
|
if (fShutdownProcess != NULL)
|
||||||
|
fShutdownProcess->PostMessage(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// roster requests
|
// roster requests
|
||||||
case B_REG_ADD_APP:
|
case B_REG_ADD_APP:
|
||||||
|
|||||||
@@ -62,13 +62,13 @@ static const bigtime_t kNonAppQuitTimeout = 500000; // 0.5 s
|
|||||||
static const bigtime_t kDisplayAbortingAppTimeout = 3000000; // 3 s
|
static const bigtime_t kDisplayAbortingAppTimeout = 3000000; // 3 s
|
||||||
|
|
||||||
|
|
||||||
// message what fields
|
// message what fields (must not clobber the registrar's message namespace)
|
||||||
enum {
|
enum {
|
||||||
MSG_PHASE_TIMED_OUT = 'phto',
|
MSG_PHASE_TIMED_OUT = 'phto',
|
||||||
MSG_DONE = 'done',
|
MSG_DONE = 'done',
|
||||||
MSG_KILL_APPLICATION = 'kill',
|
MSG_KILL_APPLICATION = 'kill',
|
||||||
MSG_CANCEL_SHUTDOWN = 'cncl',
|
MSG_CANCEL_SHUTDOWN = 'cncl',
|
||||||
MSG_REBOOT_SYSTEM = 'rbot',
|
MSG_REBOOT_SYSTEM = 'lbot',
|
||||||
};
|
};
|
||||||
|
|
||||||
// internal events
|
// internal events
|
||||||
@@ -79,6 +79,7 @@ enum {
|
|||||||
APP_QUIT_EVENT,
|
APP_QUIT_EVENT,
|
||||||
KILL_APP_EVENT,
|
KILL_APP_EVENT,
|
||||||
REBOOT_SYSTEM_EVENT,
|
REBOOT_SYSTEM_EVENT,
|
||||||
|
DEBUG_EVENT
|
||||||
};
|
};
|
||||||
|
|
||||||
// phases
|
// phases
|
||||||
@@ -790,21 +791,15 @@ PRINT(("MSG_PHASE_TIMED_OUT: phase: %ld, team: %ld\n", phase, team));
|
|||||||
if (message->FindInt32("team", &team) != B_OK)
|
if (message->FindInt32("team", &team) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BAutolock _(fWorkerLock);
|
|
||||||
|
|
||||||
// post the event
|
// post the event
|
||||||
_PushEvent(KILL_APP_EVENT, team, fCurrentPhase);
|
_PushEvent(KILL_APP_EVENT, team, fCurrentPhase);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MSG_CANCEL_SHUTDOWN:
|
case MSG_CANCEL_SHUTDOWN:
|
||||||
{
|
{
|
||||||
BAutolock _(fWorkerLock);
|
|
||||||
|
|
||||||
// post the event
|
// post the event
|
||||||
_PushEvent(ABORT_EVENT, -1, fCurrentPhase);
|
_PushEvent(ABORT_EVENT, -1, fCurrentPhase);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,7 +807,6 @@ PRINT(("MSG_PHASE_TIMED_OUT: phase: %ld, team: %ld\n", phase, team));
|
|||||||
{
|
{
|
||||||
// post the event
|
// post the event
|
||||||
_PushEvent(REBOOT_SYSTEM_EVENT, -1, INVALID_PHASE);
|
_PushEvent(REBOOT_SYSTEM_EVENT, -1, INVALID_PHASE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,7 +814,34 @@ PRINT(("MSG_PHASE_TIMED_OUT: phase: %ld, team: %ld\n", phase, team));
|
|||||||
{
|
{
|
||||||
// notify the registrar that we're done
|
// notify the registrar that we're done
|
||||||
be_app->PostMessage(B_REG_SHUTDOWN_FINISHED, be_app);
|
be_app->PostMessage(B_REG_SHUTDOWN_FINISHED, be_app);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_REG_TEAM_DEBUGGER_ALERT:
|
||||||
|
{
|
||||||
|
bool stopShutdown;
|
||||||
|
if (message->FindBool("stop shutdown", &stopShutdown) == B_OK
|
||||||
|
&& stopShutdown) {
|
||||||
|
// post abort event to the worker
|
||||||
|
_PushEvent(ABORT_EVENT, -1, fCurrentPhase);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool open;
|
||||||
|
team_id team;
|
||||||
|
if (message->FindInt32("team", &team) != B_OK
|
||||||
|
|| message->FindBool("open", &open) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BAutolock _(fWorkerLock);
|
||||||
|
if (open) {
|
||||||
|
PRINT(("B_REG_TEAM_DEBUGGER_ALERT: insert %ld\n", team));
|
||||||
|
fDebuggedTeams.insert(team);
|
||||||
|
} else {
|
||||||
|
PRINT(("B_REG_TEAM_DEBUGGER_ALERT: remove %ld\n", team));
|
||||||
|
fDebuggedTeams.erase(team);
|
||||||
|
_PushEvent(DEBUG_EVENT, -1, fCurrentPhase);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1145,10 +1166,9 @@ ShutdownProcess::_GetNextEvent(uint32 &eventType, thread_id &team, int32 &phase,
|
|||||||
do {
|
do {
|
||||||
error = acquire_sem(fInternalEventSemaphore);
|
error = acquire_sem(fInternalEventSemaphore);
|
||||||
} while (error == B_INTERRUPTED);
|
} while (error == B_INTERRUPTED);
|
||||||
|
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
status_t error = acquire_sem_etc(fInternalEventSemaphore, 1,
|
status_t error = acquire_sem_etc(fInternalEventSemaphore, 1,
|
||||||
B_RELATIVE_TIMEOUT, 0);
|
B_RELATIVE_TIMEOUT, 0);
|
||||||
@@ -1157,10 +1177,10 @@ ShutdownProcess::_GetNextEvent(uint32 &eventType, thread_id &team, int32 &phase,
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the event
|
// get the event
|
||||||
BAutolock _(fWorkerLock);
|
BAutolock _(fWorkerLock);
|
||||||
|
|
||||||
InternalEvent *event = fInternalEvents->Head();
|
InternalEvent *event = fInternalEvents->Head();
|
||||||
fInternalEvents->Remove(event);
|
fInternalEvents->Remove(event);
|
||||||
|
|
||||||
@@ -1259,14 +1279,17 @@ ShutdownProcess::_WorkerDoShutdown()
|
|||||||
// phase 1: terminate the user apps
|
// phase 1: terminate the user apps
|
||||||
_SetPhase(USER_APP_TERMINATION_PHASE);
|
_SetPhase(USER_APP_TERMINATION_PHASE);
|
||||||
_QuitApps(fUserApps, false);
|
_QuitApps(fUserApps, false);
|
||||||
|
_WaitForDebuggedTeams();
|
||||||
|
|
||||||
// phase 2: terminate the system apps
|
// phase 2: terminate the system apps
|
||||||
_SetPhase(SYSTEM_APP_TERMINATION_PHASE);
|
_SetPhase(SYSTEM_APP_TERMINATION_PHASE);
|
||||||
_QuitApps(fSystemApps, true);
|
_QuitApps(fSystemApps, true);
|
||||||
|
_WaitForDebuggedTeams();
|
||||||
|
|
||||||
// phase 3: terminate the background apps
|
// phase 3: terminate the background apps
|
||||||
_SetPhase(BACKGROUND_APP_TERMINATION_PHASE);
|
_SetPhase(BACKGROUND_APP_TERMINATION_PHASE);
|
||||||
_QuitBackgroundApps();
|
_QuitBackgroundApps();
|
||||||
|
_WaitForDebuggedTeams();
|
||||||
|
|
||||||
// phase 4: terminate the other processes
|
// phase 4: terminate the other processes
|
||||||
_SetPhase(OTHER_PROCESSES_TERMINATION_PHASE);
|
_SetPhase(OTHER_PROCESSES_TERMINATION_PHASE);
|
||||||
@@ -1274,6 +1297,7 @@ ShutdownProcess::_WorkerDoShutdown()
|
|||||||
_ScheduleTimeoutEvent(kBackgroundAppQuitTimeout, -1);
|
_ScheduleTimeoutEvent(kBackgroundAppQuitTimeout, -1);
|
||||||
_WaitForBackgroundApps();
|
_WaitForBackgroundApps();
|
||||||
_KillBackgroundApps();
|
_KillBackgroundApps();
|
||||||
|
_WaitForDebuggedTeams();
|
||||||
|
|
||||||
// we're through: do the shutdown
|
// we're through: do the shutdown
|
||||||
_SetPhase(DONE_PHASE);
|
_SetPhase(DONE_PHASE);
|
||||||
@@ -1311,7 +1335,49 @@ ShutdownProcess::_WorkerDoShutdown()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// _QuitApps
|
|
||||||
|
bool
|
||||||
|
ShutdownProcess::_WaitForApp(team_id team, AppInfoList *list, bool systemApps)
|
||||||
|
{
|
||||||
|
uint32 event;
|
||||||
|
do {
|
||||||
|
team_id eventTeam;
|
||||||
|
int32 phase;
|
||||||
|
status_t error = _GetNextEvent(event, eventTeam, phase, true);
|
||||||
|
if (error != B_OK)
|
||||||
|
throw_error(error);
|
||||||
|
|
||||||
|
if (event == APP_QUIT_EVENT && eventTeam == team)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (event == TIMEOUT_EVENT && eventTeam == team)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (event == ABORT_EVENT) {
|
||||||
|
if (systemApps) {
|
||||||
|
// If the app requests aborting the shutdown, we don't need
|
||||||
|
// to wait any longer. It has processed the request and
|
||||||
|
// won't quit by itself. We ignore this for system apps.
|
||||||
|
if (eventTeam == team)
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
PRINT(("ShutdownProcess::_QuitApps(): shutdown cancelled "
|
||||||
|
"by team %ld (-1 => user)\n", eventTeam));
|
||||||
|
|
||||||
|
_DisplayAbortingApp(team);
|
||||||
|
throw_error(B_SHUTDOWN_CANCELLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BAutolock _(fWorkerLock);
|
||||||
|
if (list != NULL && !list->InfoFor(team))
|
||||||
|
return true;
|
||||||
|
} while (event != NO_EVENT);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ShutdownProcess::_QuitApps(AppInfoList &list, bool systemApps)
|
ShutdownProcess::_QuitApps(AppInfoList &list, bool systemApps)
|
||||||
{
|
{
|
||||||
@@ -1401,44 +1467,7 @@ ShutdownProcess::_QuitApps(AppInfoList &list, bool systemApps)
|
|||||||
_ScheduleTimeoutEvent(kAppQuitTimeout, team);
|
_ScheduleTimeoutEvent(kAppQuitTimeout, team);
|
||||||
|
|
||||||
// wait for the app to die or for the timeout to occur
|
// wait for the app to die or for the timeout to occur
|
||||||
bool appGone = false;
|
bool appGone = _WaitForApp(team, &list, systemApps);
|
||||||
do {
|
|
||||||
team_id eventTeam;
|
|
||||||
int32 phase;
|
|
||||||
status_t error = _GetNextEvent(event, eventTeam, phase, true);
|
|
||||||
if (error != B_OK)
|
|
||||||
throw_error(error);
|
|
||||||
|
|
||||||
if ((event == APP_QUIT_EVENT)
|
|
||||||
&& eventTeam == team) {
|
|
||||||
appGone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event == TIMEOUT_EVENT && eventTeam == team)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (event == ABORT_EVENT) {
|
|
||||||
if (systemApps) {
|
|
||||||
// If the app requests aborting the shutdown, we don't need
|
|
||||||
// to wait any longer. It has processed the request and
|
|
||||||
// won't quit by itself. We ignore this for system apps.
|
|
||||||
if (eventTeam == team)
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
PRINT(("ShutdownProcess::_QuitApps(): shutdown cancelled "
|
|
||||||
"by team %ld (-1 => user)\n", eventTeam));
|
|
||||||
|
|
||||||
_DisplayAbortingApp(team);
|
|
||||||
throw_error(B_SHUTDOWN_CANCELLED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BAutolock _(fWorkerLock);
|
|
||||||
if (!list.InfoFor(team))
|
|
||||||
break;
|
|
||||||
|
|
||||||
} while (event != NO_EVENT);
|
|
||||||
|
|
||||||
if (appGone) {
|
if (appGone) {
|
||||||
// fine: the app finished in an orderly manner
|
// fine: the app finished in an orderly manner
|
||||||
} else {
|
} else {
|
||||||
@@ -1623,7 +1652,17 @@ void
|
|||||||
ShutdownProcess::_QuitBlockingApp(AppInfoList &list, team_id team,
|
ShutdownProcess::_QuitBlockingApp(AppInfoList &list, team_id team,
|
||||||
const char *appName, bool cancelAllowed)
|
const char *appName, bool cancelAllowed)
|
||||||
{
|
{
|
||||||
if (BPrivate::is_app_showing_modal_window(team)) {
|
bool debugged = false;
|
||||||
|
bool modal = false;
|
||||||
|
{
|
||||||
|
BAutolock _(fWorkerLock);
|
||||||
|
if (fDebuggedTeams.find(team) != fDebuggedTeams.end())
|
||||||
|
debugged = true;
|
||||||
|
}
|
||||||
|
if (!debugged)
|
||||||
|
modal = BPrivate::is_app_showing_modal_window(team);
|
||||||
|
|
||||||
|
if (modal) {
|
||||||
// app blocks on a modal window
|
// app blocks on a modal window
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
snprintf(buffer, sizeof(buffer), "The application \"%s\" might be "
|
snprintf(buffer, sizeof(buffer), "The application \"%s\" might be "
|
||||||
@@ -1631,7 +1670,9 @@ ShutdownProcess::_QuitBlockingApp(AppInfoList &list, team_id team,
|
|||||||
_SetShutdownWindowText(buffer);
|
_SetShutdownWindowText(buffer);
|
||||||
_SetShutdownWindowCurrentApp(team);
|
_SetShutdownWindowCurrentApp(team);
|
||||||
_SetShutdownWindowKillButtonEnabled(true);
|
_SetShutdownWindowKillButtonEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modal || debugged) {
|
||||||
// wait for something to happen
|
// wait for something to happen
|
||||||
bool appGone = false;
|
bool appGone = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -1651,7 +1692,7 @@ ShutdownProcess::_QuitBlockingApp(AppInfoList &list, team_id team,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (event == ABORT_EVENT) {
|
if (event == ABORT_EVENT) {
|
||||||
if (cancelAllowed) {
|
if (cancelAllowed || debugged) {
|
||||||
PRINT(("ShutdownProcess::_QuitBlockingApp(): shutdown "
|
PRINT(("ShutdownProcess::_QuitBlockingApp(): shutdown "
|
||||||
"cancelled by team %ld (-1 => user)\n", eventTeam));
|
"cancelled by team %ld (-1 => user)\n", eventTeam));
|
||||||
|
|
||||||
@@ -1758,3 +1799,39 @@ ShutdownProcess::_DisplayAbortingApp(team_id team)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Waits until the debugged team list is empty, ie. when there is no one
|
||||||
|
left to debug.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ShutdownProcess::_WaitForDebuggedTeams()
|
||||||
|
{
|
||||||
|
PRINT(("ShutdownProcess::_WaitForDebuggedTeams()\n"));
|
||||||
|
{
|
||||||
|
BAutolock _(fWorkerLock);
|
||||||
|
if (fDebuggedTeams.empty())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT((" not empty!\n"));
|
||||||
|
|
||||||
|
// wait for something to happen
|
||||||
|
while (true) {
|
||||||
|
uint32 event;
|
||||||
|
team_id eventTeam;
|
||||||
|
int32 phase;
|
||||||
|
status_t error = _GetNextEvent(event, eventTeam, phase, true);
|
||||||
|
if (error != B_OK)
|
||||||
|
throw_error(error);
|
||||||
|
|
||||||
|
if (event == ABORT_EVENT)
|
||||||
|
throw_error(B_SHUTDOWN_CANCELLED);
|
||||||
|
|
||||||
|
BAutolock _(fWorkerLock);
|
||||||
|
if (fDebuggedTeams.empty()) {
|
||||||
|
PRINT((" out empty"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ private:
|
|||||||
status_t _Worker();
|
status_t _Worker();
|
||||||
|
|
||||||
void _WorkerDoShutdown();
|
void _WorkerDoShutdown();
|
||||||
|
bool _WaitForApp(team_id team, AppInfoList *list, bool systemApps);
|
||||||
void _QuitApps(AppInfoList &list, bool systemApps);
|
void _QuitApps(AppInfoList &list, bool systemApps);
|
||||||
void _QuitBackgroundApps();
|
void _QuitBackgroundApps();
|
||||||
void _WaitForBackgroundApps();
|
void _WaitForBackgroundApps();
|
||||||
@@ -78,6 +79,7 @@ private:
|
|||||||
void _QuitBlockingApp(AppInfoList &list, team_id team, const char *appName,
|
void _QuitBlockingApp(AppInfoList &list, team_id team, const char *appName,
|
||||||
bool cancelAllowed);
|
bool cancelAllowed);
|
||||||
void _DisplayAbortingApp(team_id team);
|
void _DisplayAbortingApp(team_id team);
|
||||||
|
void _WaitForDebuggedTeams();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class TimeoutEvent;
|
class TimeoutEvent;
|
||||||
@@ -97,6 +99,7 @@ private:
|
|||||||
AppInfoList fSystemApps;
|
AppInfoList fSystemApps;
|
||||||
AppInfoList fUserApps;
|
AppInfoList fUserApps;
|
||||||
AppInfoList fBackgroundApps;
|
AppInfoList fBackgroundApps;
|
||||||
|
hash_set<team_id> fDebuggedTeams;
|
||||||
TimeoutEvent *fTimeoutEvent;
|
TimeoutEvent *fTimeoutEvent;
|
||||||
InternalEventList *fInternalEvents;
|
InternalEventList *fInternalEvents;
|
||||||
sem_id fInternalEventSemaphore;
|
sem_id fInternalEventSemaphore;
|
||||||
|
|||||||
Reference in New Issue
Block a user