summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llapp.cpp20
-rw-r--r--indra/llcommon/llapp.h38
-rw-r--r--indra/llcommon/llthread.h1
-rw-r--r--indra/llcommon/lluuid.cpp1
4 files changed, 50 insertions, 10 deletions
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index a90b294550..34f6ba140a 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -113,7 +113,8 @@ BOOL LLApp::sDisableCrashlogger = FALSE;
BOOL LLApp::sLogInSignal = FALSE;
// static
-LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status
+// Keeps track of application status
+LLScalarCond<LLApp::EAppStatus> LLApp::sStatus{LLApp::APP_STATUS_STOPPED};
LLAppErrorHandler LLApp::sErrorHandler = NULL;
BOOL LLApp::sErrorThreadRunning = FALSE;
@@ -579,7 +580,8 @@ static std::map<LLApp::EAppStatus, const char*> statusDesc
// static
void LLApp::setStatus(EAppStatus status)
{
- sStatus = status;
+ // notify everyone waiting on sStatus any time its value changes
+ sStatus.set_all(status);
// This can also happen very late in the application lifecycle -- don't
// resurrect a deleted LLSingleton
@@ -609,6 +611,12 @@ void LLApp::setError()
setStatus(APP_STATUS_ERROR);
}
+// static
+bool LLApp::sleep(F32Milliseconds duration)
+{
+ return ! sStatus.wait_for_unequal(duration, APP_STATUS_RUNNING);
+}
+
void LLApp::setMiniDumpDir(const std::string &path)
{
if (path.empty())
@@ -668,28 +676,28 @@ void LLApp::setStopped()
// static
bool LLApp::isStopped()
{
- return (APP_STATUS_STOPPED == sStatus);
+ return (APP_STATUS_STOPPED == sStatus.get());
}
// static
bool LLApp::isRunning()
{
- return (APP_STATUS_RUNNING == sStatus);
+ return (APP_STATUS_RUNNING == sStatus.get());
}
// static
bool LLApp::isError()
{
- return (APP_STATUS_ERROR == sStatus);
+ return (APP_STATUS_ERROR == sStatus.get());
}
// static
bool LLApp::isQuitting()
{
- return (APP_STATUS_QUITTING == sStatus);
+ return (APP_STATUS_QUITTING == sStatus.get());
}
// static
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 245c73e3a2..e95929b865 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -28,9 +28,11 @@
#define LL_LLAPP_H
#include <map>
+#include "llcond.h"
#include "llrun.h"
#include "llsd.h"
#include <atomic>
+#include <chrono>
// Forward declarations
class LLErrorThread;
class LLLiveFile;
@@ -211,6 +213,36 @@ public:
static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
static int getPid();
+ //
+ // Sleep for specified time while still running
+ //
+ // For use by a coroutine or thread that performs some maintenance on a
+ // periodic basis. (See also LLEventTimer.) This method supports the
+ // pattern of an "infinite" loop that sleeps for some time, performs some
+ // action, then sleeps again. The trouble with literally sleeping a worker
+ // thread is that it could potentially sleep right through attempted
+ // application shutdown. This method avoids that by returning false as
+ // soon as the application status changes away from APP_STATUS_RUNNING
+ // (isRunning()).
+ //
+ // sleep() returns true if it sleeps undisturbed for the entire specified
+ // duration. The idea is that you can code 'while sleep(duration) ...',
+ // which will break the loop once shutdown begins.
+ //
+ // Since any time-based LLUnit should be implicitly convertible to
+ // F32Milliseconds, accept that specific type as a proxy.
+ static bool sleep(F32Milliseconds duration);
+ // Allow any duration defined in terms of <chrono>.
+ // One can imagine a wonderfully general bidirectional conversion system
+ // between any type derived from LLUnits::LLUnit<T, LLUnits::Seconds> and
+ // any std::chrono::duration -- but that doesn't yet exist.
+ template <typename Rep, typename Period>
+ bool sleep(const std::chrono::duration<Rep, Period>& duration)
+ {
+ // wait_for_unequal() has the opposite bool return convention
+ return ! sStatus.wait_for_unequal(duration, APP_STATUS_RUNNING);
+ }
+
/** @name Error handling methods */
//@{
/**
@@ -241,8 +273,8 @@ public:
// Return the Google Breakpad minidump filename after a crash.
char *getMiniDumpFilename() { return mMinidumpPath; }
- std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
- std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
+ std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
+ std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
// Write out a Google Breakpad minidump file.
void writeMiniDump();
@@ -266,7 +298,7 @@ public:
protected:
static void setStatus(EAppStatus status); // Use this to change the application status.
- static EAppStatus sStatus; // Reflects current application status
+ static LLScalarCond<EAppStatus> sStatus; // Reflects current application status
static BOOL sErrorThreadRunning; // Set while the error thread is running
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 5cd0731f6c..50202631e7 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -27,7 +27,6 @@
#ifndef LL_LLTHREAD_H
#define LL_LLTHREAD_H
-#include "llapp.h"
#include "llapr.h"
#include "boost/intrusive_ptr.hpp"
#include "llrefcount.h"
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index b05630c6b5..b4879c2489 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -33,6 +33,7 @@
#include <iphlpapi.h>
#endif
+#include "llapp.h"
#include "lldefs.h"
#include "llerror.h"