MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / ExitApp

Method ExitApp

source/script.cpp:1378–1454  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1376
1377
1378ResultType Script::ExitApp(ExitReasons aExitReason, int aExitCode)
1379// Normal exit (if aBuf is NULL), or a way to exit immediately on error (which is mostly
1380// for times when it would be unsafe to call MsgBox() due to the possibility that it would
1381// make the situation even worse).
1382{
1383 mExitReason = aExitReason;
1384 // Note that currently, mOnExit.Count() can only be non-zero if the script is in a runnable
1385 // state (since registering an OnExit function requires that the script calls OnExit()).
1386 // If this ever changes, the !mIsReadyToExecute condition should be added below:
1387 if (!mOnExit.Count() || g_OnExitIsRunning)
1388 {
1389 // In the case of g_OnExitIsRunning == true:
1390 // There is another instance of this function beneath us on the stack. Since we have
1391 // been called, this is a true exit condition and we exit immediately.
1392 // MUST NOT create a new thread when g_OnExitIsRunning because g_array allows only one
1393 // extra thread for ExitApp() (which allows it to run even when MAX_THREADS_EMERGENCY has
1394 // been reached). See TOTAL_ADDITIONAL_THREADS.
1395 TerminateApp(aExitReason, aExitCode);
1396 }
1397
1398 // Otherwise, the script contains the special OnExit function that we will run here instead
1399 // of exiting. And since it does, we know that the script is in a ready-to-execute state
1400 // because that is the only way an OnExit function could have been defined in the first place.
1401 // The OnExit function may return true in order to abort the Exit sequence (e.g. it could
1402 // display an "Are you sure?" prompt, and if the user chooses "No", it returns true, letting
1403 // the thread we create below end normally).
1404
1405 // Next, save the current state of the globals so that they can be restored just prior
1406 // to returning to our caller:
1407 InitNewThread(0, true, true); // Uninterruptibility is handled below. Since this special thread should always run, no checking of g_MaxThreadsTotal is done before calling this.
1408
1409 // Turn on uninterruptibility to forbid any hotkeys, timers, or user defined menu items
1410 // to interrupt. This is mainly done for peace-of-mind (since possible interactions due to
1411 // interruptions have not been studied) and the fact that this most users would not want this
1412 // subroutine to be interruptible (it usually runs quickly anyway). Another reason to make
1413 // it non-interruptible is that some OnExit functions might destruct things used by the
1414 // script's hotkeys/timers/menu items, and activating these items during the deconstruction
1415 // would not be safe. Finally, if a logoff or shutdown is occurring, it seems best to prevent
1416 // timed subroutines from running -- which might take too much time and prevent the exit from
1417 // occurring in a timely fashion. An option can be added via the FutureUse param to make it
1418 // interruptible if there is ever a demand for that.
1419 // UPDATE: g_AllowInterruption is now used instead of g->AllowThreadToBeInterrupted for two reasons:
1420 // 1) It avoids the need to do "int mUninterruptedLineCountMax_prev = g_script.mUninterruptedLineCountMax;"
1421 // (Disable this item so that ExecUntil() won't automatically make our new thread uninterruptible
1422 // after it has executed a certain number of lines).
1423 // 2) Mostly obsolete: If the thread we're interrupting is uninterruptible, the uninterruptible timer
1424 // might be currently pending. When it fires, it would make the OnExit function interruptible
1425 // rather than the underlying subroutine. The above fixes the first part of that problem.
1426 // The 2nd part is fixed by reinstating the timer when the uninterruptible thread is resumed.
1427 // This special handling is only necessary here -- not in other places where new threads are
1428 // created -- because OnExit is the only type of thread that can interrupt an uninterruptible
1429 // thread.
1430 BOOL g_AllowInterruption_prev = g_AllowInterruption; // Save current setting.
1431 g_AllowInterruption = FALSE; // Mark the thread just created above as permanently uninterruptible (i.e. until it finishes and is destroyed).
1432
1433 g_OnExitIsRunning = true;
1434 DEBUGGER_STACK_PUSH(_T("OnExit"))
1435

Callers 9

AutoExecSectionMethod · 0.80
ExitIfNotPersistentMethod · 0.80
PerformMethod · 0.80
MainWindowProcFunction · 0.80
HandleMenuItemFunction · 0.80
ConnectMethod · 0.80
FatalErrorMethod · 0.80
MsgSleepFunction · 0.80

Calls 5

InitNewThreadFunction · 0.85
GetExitReasonStringFunction · 0.85
ResumeUnderlyingThreadFunction · 0.85
CountMethod · 0.45
CallMethod · 0.45

Tested by

no test coverage detected