summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llapp.cpp56
-rw-r--r--indra/llcommon/llapp.h4
-rw-r--r--indra/llcommon/llapr.cpp7
-rw-r--r--indra/llcommon/llcoros.h9
-rw-r--r--indra/llcommon/lldate.cpp9
-rw-r--r--indra/llcommon/lldate.h9
-rw-r--r--indra/llcommon/llerror.cpp19
-rw-r--r--indra/llcommon/llerrorcontrol.h2
-rw-r--r--indra/llcommon/lleventfilter.h2
-rw-r--r--indra/llcommon/llfile.cpp18
-rw-r--r--indra/llcommon/llfile.h2
-rw-r--r--indra/llcommon/llmemory.cpp85
-rw-r--r--indra/llcommon/llmutex.cpp36
-rw-r--r--indra/llcommon/llpointer.h111
-rw-r--r--indra/llcommon/llpreprocessor.h5
-rw-r--r--indra/llcommon/llprofiler.h2
-rw-r--r--indra/llcommon/llqueuedthread.cpp2
-rw-r--r--indra/llcommon/llrand.cpp2
-rw-r--r--indra/llcommon/llsd.cpp242
-rw-r--r--indra/llcommon/llsd.h50
-rw-r--r--indra/llcommon/llsdparam.cpp2
-rw-r--r--indra/llcommon/llsdserialize.cpp18
-rw-r--r--indra/llcommon/llsdserialize_xml.cpp4
-rw-r--r--indra/llcommon/llsdutil.cpp43
-rw-r--r--indra/llcommon/llsingleton.h7
-rw-r--r--indra/llcommon/llstl.h6
-rw-r--r--indra/llcommon/llstring.cpp71
-rw-r--r--indra/llcommon/llstring.h14
-rw-r--r--indra/llcommon/llsys.cpp51
-rw-r--r--indra/llcommon/llsys.h5
-rw-r--r--indra/llcommon/llthread.cpp14
-rw-r--r--indra/llcommon/lltimer.cpp6
-rw-r--r--indra/llcommon/lltraceaccumulators.cpp18
-rw-r--r--indra/llcommon/lltraceaccumulators.h26
-rw-r--r--indra/llcommon/lltracerecording.cpp14
-rw-r--r--indra/llcommon/lltracerecording.h9
-rw-r--r--indra/llcommon/llunittype.h9
-rw-r--r--indra/llcommon/tests/lleventfilter_test.cpp14
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp2
-rw-r--r--indra/llcommon/tests/lltrace_test.cpp4
-rw-r--r--indra/llcommon/tests/llunits_test.cpp2
41 files changed, 702 insertions, 309 deletions
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index b85bd2573b..6da764f94c 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -90,7 +90,7 @@ bool LLApp::sDisableCrashlogger = false;
// Local flag for whether or not to do logging in signal handlers.
//static
-bool LLApp::sLogInSignal = false;
+bool LLApp::sLogInSignal = true;
// static
// Keeps track of application status
@@ -373,6 +373,9 @@ static std::map<LLApp::EAppStatus, const char*> statusDesc
// static
void LLApp::setStatus(EAppStatus status)
{
+ auto status_it = statusDesc.find(status);
+ std::string status_text = status_it != statusDesc.end() ? std::string(status_it->second) : std::to_string(status);
+ LL_INFOS() << "status: " << status_text << LL_ENDL;
// notify everyone waiting on sStatus any time its value changes
sStatus.set_all(status);
@@ -381,18 +384,7 @@ void LLApp::setStatus(EAppStatus status)
if (! LLEventPumps::wasDeleted())
{
// notify interested parties of status change
- LLSD statsd;
- auto found = statusDesc.find(status);
- if (found != statusDesc.end())
- {
- statsd = found->second;
- }
- else
- {
- // unknown status? at least report value
- statsd = LLSD::Integer(status);
- }
- LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", statsd));
+ LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", status_text));
}
}
@@ -487,6 +479,33 @@ int LLApp::getPid()
#endif
}
+// static
+void LLApp::notifyOutOfDiskSpace()
+{
+ static const U32Seconds min_interval = U32Seconds(60);
+ static U32Seconds min_time_to_send = U32Seconds(0);
+ U32Seconds now = LLTimer::getTotalTime();
+ if (now < min_time_to_send)
+ return;
+
+ min_time_to_send = now + min_interval;
+
+ if (LLApp* app = instance())
+ {
+ app->sendOutOfDiskSpaceNotification();
+ }
+ else
+ {
+ LL_WARNS() << "No app instance" << LL_ENDL;
+ }
+}
+
+// virtual
+void LLApp::sendOutOfDiskSpaceNotification()
+{
+ LL_WARNS() << "Should never be called" << LL_ENDL; // Should be overridden
+}
+
#ifndef LL_WINDOWS
void setup_signals()
{
@@ -654,6 +673,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
{
LL_WARNS() << "Signal handler - Handling fatal signal!" << LL_ENDL;
}
+
if (LLApp::isError())
{
// Received second fatal signal while handling first, just die right now
@@ -691,11 +711,11 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
clear_signals();
raise(signum);
return;
- } else {
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;
- }
+ }
+
+ if (LLApp::sLogInSignal)
+ {
+ LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;
}
}
}
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index ad8912ca88..d90ecdf661 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -202,6 +202,8 @@ public:
static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
static int getPid();
+ static void notifyOutOfDiskSpace();
+
//
// Sleep for specified time while still running
//
@@ -301,6 +303,8 @@ protected:
*/
void stepFrame();
+ virtual void sendOutOfDiskSpaceNotification();
+
private:
// Contains the filename of the minidump file after a crash.
char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH];
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index b085f8f5dc..01763c49aa 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llapr.h"
+#include "llapp.h"
#include "llmutex.h"
#include "apr_dso.h"
@@ -606,7 +607,11 @@ S32 LLAPRFile::writeEx(const std::string& filename, const void *buf, S32 offset,
apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);
if (s != APR_SUCCESS)
{
- LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL;
+ LL_WARNS("APR") << "Attempting to write filename: " << filename << LL_ENDL;
+ if (APR_STATUS_IS_ENOSPC(s))
+ {
+ LLApp::notifyOutOfDiskSpace();
+ }
ll_apr_warn_status(s);
bytes_written = 0;
}
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 369d65407e..c3820ae987 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -31,8 +31,9 @@
#include "llexception.h"
#include <boost/fiber/fss.hpp>
-#include <boost/fiber/future/promise.hpp>
#include <boost/fiber/future/future.hpp>
+#include <boost/fiber/future/promise.hpp>
+#include <boost/fiber/recursive_mutex.hpp>
#include "mutex.h"
#include "llsingleton.h"
#include "llinstancetracker.h"
@@ -307,6 +308,12 @@ public:
// use mutex, lock, condition_variable suitable for coroutines
using Mutex = boost::fibers::mutex;
+ using RMutex = boost::fibers::recursive_mutex;
+ // With C++17, LockType is deprecated: at this point we can directly
+ // declare 'std::unique_lock lk(some_mutex)' without explicitly stating
+ // the mutex type. Sadly, making LockType an alias template for
+ // std::unique_lock doesn't work the same way: Class Template Argument
+ // Deduction only works for class templates, not alias templates.
using LockType = std::unique_lock<Mutex>;
using cv_status = boost::fibers::cv_status;
using ConditionVariable = boost::fibers::condition_variable;
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index c63c7012d1..b38864688d 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -41,20 +41,11 @@
#include "llstring.h"
#include "llfasttimer.h"
-static const F64 DATE_EPOCH = 0.0;
-
static const F64 LL_APR_USEC_PER_SEC = 1000000.0;
// should be APR_USEC_PER_SEC, but that relies on INT64_C which
// isn't defined in glib under our build set up for some reason
-LLDate::LLDate() : mSecondsSinceEpoch(DATE_EPOCH)
-{}
-
-LLDate::LLDate(const LLDate& date) :
- mSecondsSinceEpoch(date.mSecondsSinceEpoch)
-{}
-
LLDate::LLDate(F64SecondsImplicit seconds_since_epoch) :
mSecondsSinceEpoch(seconds_since_epoch.value())
{}
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 81f2dd0d1c..1a69a04232 100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -43,16 +43,13 @@
*/
class LL_COMMON_API LLDate
{
+ static constexpr F64 DATE_EPOCH = 0.0;
public:
/**
* @brief Construct a date equal to epoch.
*/
- LLDate();
-
- /**
- * @brief Construct a date equal to the source date.
- */
- LLDate(const LLDate& date);
+ constexpr LLDate() : mSecondsSinceEpoch(DATE_EPOCH)
+ {}
/**
* @brief Construct a date from a seconds since epoch value.
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index fa24987d1c..6c3b9c9542 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -55,7 +55,6 @@
#include "llsingleton.h"
#include "llstl.h"
#include "lltimer.h"
-#include <boost/fiber/recursive_mutex.hpp>
// On Mac, got:
// #error "Boost.Stacktrace requires `_Unwind_Backtrace` function. Define
@@ -168,7 +167,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
if (LLError::getAlwaysFlush())
{
mFile << message << std::endl;
@@ -235,7 +234,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
// The default colors for error, warn and debug are now a bit more pastel
// and easier to read on the default (black) terminal background but you
// now have the option to set the color of each via an environment variables:
@@ -275,7 +274,7 @@ namespace {
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
static std::string s_ansi_bold = createBoldANSI(); // bold text
static std::string s_ansi_reset = createResetANSI(); // reset
// ANSI color code escape sequence, message, and reset in one fprintf call
@@ -312,7 +311,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
mBuffer->addLine(message);
}
@@ -339,7 +338,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
debugger_print(message);
}
};
@@ -507,7 +506,7 @@ namespace
LLError::TimeFunction mTimeFunction;
Recorders mRecorders;
- boost::fibers::recursive_mutex mRecorderMutex;
+ LLCoros::RMutex mRecorderMutex;
int mShouldLogCallCounter;
@@ -1216,7 +1215,7 @@ namespace
void writeToRecorders(const LLError::CallSite& site, const std::string& message)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
LLError::ELevel level = site.mLevel;
SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
@@ -1347,7 +1346,7 @@ namespace LLError
bool Log::shouldLog(CallSite& site)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5);
if (!lock.isLocked())
{
@@ -1392,7 +1391,7 @@ namespace LLError
void Log::flush(const std::ostringstream& out, const CallSite& site)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
if (!lock.isLocked())
{
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index bf5a6df556..2be443ca37 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -190,7 +190,7 @@ namespace LLError
{}
void recordMessage(LLError::ELevel level, const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
mCallable(level, message);
}
private:
diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h
index 5c45144fad..d8c7e15a27 100644
--- a/indra/llcommon/lleventfilter.h
+++ b/indra/llcommon/lleventfilter.h
@@ -429,7 +429,7 @@ public:
// path, then stores it to mTarget.
virtual bool post(const LLSD& event)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// Extract the element specified by 'mPath' from 'event'. To perform a
// generic type-appropriate store through mTarget, construct an
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index ddf239f306..9045324bf2 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -248,6 +248,24 @@ int LLFile::close(LLFILE * file)
return ret_value;
}
+std::string LLFile::getContents(const std::string& filename)
+{
+ LLFILE* fp = fopen(filename, "rb"); /* Flawfinder: ignore */
+ if (fp)
+ {
+ fseek(fp, 0, SEEK_END);
+ U32 length = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<char> buffer(length);
+ size_t nread = fread(buffer.data(), 1, length, fp);
+ fclose(fp);
+
+ return std::string(buffer.data(), nread);
+ }
+
+ return LLStringUtil::null;
+}
int LLFile::remove(const std::string& filename, int supress_error)
{
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index 2564671b13..74110343fc 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -67,6 +67,8 @@ public:
static int close(LLFILE * file);
+ static std::string getContents(const std::string& filename);
+
// perms is a permissions mask like 0777 or 0700. In most cases it will
// be overridden by the user's umask. It is ignored on Windows.
// mkdir() considers "directory already exists" to be SUCCESS.
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 4b7d60d654..99c803e46f 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -39,6 +39,7 @@
#elif LL_LINUX
# include <unistd.h>
# include <sys/resource.h>
+# include <sys/sysinfo.h>
#endif
#include "llmemory.h"
@@ -50,13 +51,28 @@
//----------------------------------------------------------------------------
//static
+
+// most important memory metric for texture streaming
+// On Windows, this should agree with resource monitor -> performance -> memory -> available
+// On OS X, this should be activity monitor -> memory -> (physical memory - memory used)
+// NOTE: this number MAY be less than the actual available memory on systems with more than MaxHeapSize64 GB of physical memory (default 16GB)
+// In that case, should report min(available, sMaxHeapSizeInKB-sAllocateMemInKB)
U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
+
+// Installed physical memory
U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0);
-static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
-static LLTrace::SampleStatHandle<F64Megabytes> sVirtualMem("virtual_mem", "virtual memory assigned to application");
+
+// Maximimum heap size according to the user's settings (default 16GB)
+U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
+
+// Current memory usage
U32Kilobytes LLMemory::sAllocatedMemInKB(0);
+
U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
-U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
+
+
+static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
+static LLTrace::SampleStatHandle<F64Megabytes> sVirtualMem("virtual_mem", "virtual memory assigned to application");
void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
{
@@ -84,7 +100,14 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size)
//static
void LLMemory::updateMemoryInfo()
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
+
+ sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB();
+
+ U32Kilobytes avail_mem;
+ LLMemoryInfo::getAvailableMemoryKB(avail_mem);
+ sAvailPhysicalMemInKB = avail_mem;
+
#if LL_WINDOWS
PROCESS_MEMORY_COUNTERS counters;
@@ -95,23 +118,9 @@ void LLMemory::updateMemoryInfo()
}
sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(counters.WorkingSetSize));
- sample(sAllocatedMem, sAllocatedMemInKB);
sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(counters.PagefileUsage));
sample(sVirtualMem, sAllocatedPageSizeInKB);
- U32Kilobytes avail_phys, avail_virtual;
- LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ;
- sMaxPhysicalMemInKB = llmin(avail_phys + sAllocatedMemInKB, sMaxHeapSizeInKB);
-
- if(sMaxPhysicalMemInKB > sAllocatedMemInKB)
- {
- sAvailPhysicalMemInKB = sMaxPhysicalMemInKB - sAllocatedMemInKB ;
- }
- else
- {
- sAvailPhysicalMemInKB = U32Kilobytes(0);
- }
-
#elif defined(LL_DARWIN)
task_vm_info info;
mach_msg_type_number_t infoCount = TASK_VM_INFO_COUNT;
@@ -136,31 +145,19 @@ void LLMemory::updateMemoryInfo()
{
LL_WARNS() << "task_info failed" << LL_ENDL;
}
-
- // Total installed and available physical memory are properties of the host, not just our process.
- vm_statistics64_data_t vmstat;
- mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
- mach_port_t host = mach_host_self();
- vm_size_t page_size;
- host_page_size(host, &page_size);
- kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info_t>(&vmstat), &count);
- if (result == KERN_SUCCESS) {
- // This is what Chrome reports as 'the "Physical Memory Free" value reported by the Memory Monitor in Instruments.'
- // Note though that inactive pages are not included here and not yet free, but could become so under memory pressure.
- sAvailPhysicalMemInKB = U32Bytes(vmstat.free_count * page_size);
- sMaxPhysicalMemInKB = LLMemoryInfo::getHardwareMemSize();
- }
- else
- {
- LL_WARNS() << "task_info failed" << LL_ENDL;
- }
-
+#elif defined(LL_LINUX)
+ // Use sysinfo() to get the total physical memory.
+ struct sysinfo info;
+ sysinfo(&info);
+ sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(LLMemory::getCurrentRSS())); // represents the RAM allocated by this process only (in line with the windows implementation)
#else
//not valid for other systems for now.
+ LL_WARNS() << "LLMemory::updateMemoryInfo() not implemented for this platform." << LL_ENDL;
sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS());
- sMaxPhysicalMemInKB = U64Bytes(U32_MAX);
- sAvailPhysicalMemInKB = U64Bytes(U32_MAX);
#endif
+ sample(sAllocatedMem, sAllocatedMemInKB);
+
+ sAvailPhysicalMemInKB = llmin(sAvailPhysicalMemInKB, sMaxHeapSizeInKB - sAllocatedMemInKB);
return ;
}
@@ -192,16 +189,16 @@ void* LLMemory::tryToAlloc(void* address, U32 size)
//static
void LLMemory::logMemoryInfo(bool update)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
if(update)
{
updateMemoryInfo() ;
}
- LL_INFOS() << "Current allocated physical memory(KB): " << sAllocatedMemInKB << LL_ENDL ;
- LL_INFOS() << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << LL_ENDL ;
- LL_INFOS() << "Current available physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
- LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ;
+ LL_INFOS() << llformat("Current allocated physical memory: %.2f MB", sAllocatedMemInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current allocated page size: %.2f MB", sAllocatedPageSizeInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current available physical memory: %.2f MB", sAvailPhysicalMemInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current max usable memory: %.2f MB", sMaxPhysicalMemInKB / 1024.0) << LL_ENDL;
}
//static
diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp
index 40c651d9c1..be1ae89a25 100644
--- a/indra/llcommon/llmutex.cpp
+++ b/indra/llcommon/llmutex.cpp
@@ -100,7 +100,7 @@ void LLMutex::unlock()
bool LLMutex::isLocked()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (!mMutex.try_lock())
{
return true;
@@ -124,7 +124,7 @@ LLThread::id_t LLMutex::lockingThread() const
bool LLMutex::trylock()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (isSelfLocked())
{ //redundant lock
mCount++;
@@ -161,7 +161,7 @@ LLSharedMutex::LLSharedMutex()
bool LLSharedMutex::isLocked() const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
std::lock_guard<std::mutex> lock(mLockMutex);
return !mLockingThreads.empty();
@@ -169,7 +169,7 @@ bool LLSharedMutex::isLocked() const
bool LLSharedMutex::isThreadLocked() const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard<std::mutex> lock(mLockMutex);
@@ -179,7 +179,7 @@ bool LLSharedMutex::isThreadLocked() const
void LLSharedMutex::lockShared()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
mLockMutex.lock();
@@ -204,7 +204,7 @@ void LLSharedMutex::lockShared()
void LLSharedMutex::lockExclusive()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
mLockMutex.lock();
@@ -237,7 +237,7 @@ void LLSharedMutex::lockExclusive()
bool LLSharedMutex::trylockShared()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard<std::mutex> lock(mLockMutex);
@@ -260,7 +260,7 @@ bool LLSharedMutex::trylockShared()
bool LLSharedMutex::trylockExclusive()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard<std::mutex> lock(mLockMutex);
@@ -282,7 +282,7 @@ bool LLSharedMutex::trylockExclusive()
void LLSharedMutex::unlockShared()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard<std::mutex> lock(mLockMutex);
@@ -303,7 +303,7 @@ void LLSharedMutex::unlockShared()
void LLSharedMutex::unlockExclusive()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard<std::mutex> lock(mLockMutex);
@@ -338,20 +338,20 @@ LLCondition::~LLCondition()
void LLCondition::wait()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
std::unique_lock< std::mutex > lock(mMutex);
mCond.wait(lock);
}
void LLCondition::signal()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mCond.notify_one();
}
void LLCondition::broadcast()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mCond.notify_all();
}
@@ -364,7 +364,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex)
: mMutex(mutex),
mLocked(false)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (mMutex)
mLocked = mMutex->trylock();
}
@@ -373,7 +373,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
: mMutex(mutex),
mLocked(false)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (!mMutex)
return;
@@ -388,7 +388,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
LLMutexTrylock::~LLMutexTrylock()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (mMutex && mLocked)
mMutex->unlock();
}
@@ -400,7 +400,7 @@ LLMutexTrylock::~LLMutexTrylock()
//
LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if(mutex)
{
mutex->lock();
@@ -419,7 +419,7 @@ LLScopedLock::~LLScopedLock()
void LLScopedLock::unlock()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if(mLocked)
{
mMutex->unlock();
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index f5916f9d58..6edff9fa5e 100644
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -46,8 +46,11 @@
template <class Type> class LLPointer
{
public:
+ template<typename Subclass>
+ friend class LLPointer;
+
LLPointer() :
- mPointer(NULL)
+ mPointer(nullptr)
{
}
@@ -63,6 +66,12 @@ public:
ref();
}
+ LLPointer(LLPointer<Type>&& ptr) noexcept
+ {
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+
// Support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template<typename Subclass>
LLPointer(const LLPointer<Subclass>& ptr) :
@@ -71,6 +80,13 @@ public:
ref();
}
+ template<typename Subclass>
+ LLPointer(LLPointer<Subclass>&& ptr) noexcept :
+ mPointer(ptr.get())
+ {
+ ptr.mPointer = nullptr;
+ }
+
~LLPointer()
{
unref();
@@ -82,11 +98,11 @@ public:
const Type& operator*() const { return *mPointer; }
Type& operator*() { return *mPointer; }
- operator BOOL() const { return (mPointer != NULL); }
- operator bool() const { return (mPointer != NULL); }
- bool operator!() const { return (mPointer == NULL); }
- bool isNull() const { return (mPointer == NULL); }
- bool notNull() const { return (mPointer != NULL); }
+ operator BOOL() const { return (mPointer != nullptr); }
+ operator bool() const { return (mPointer != nullptr); }
+ bool operator!() const { return (mPointer == nullptr); }
+ bool isNull() const { return (mPointer == nullptr); }
+ bool notNull() const { return (mPointer != nullptr); }
operator Type*() const { return mPointer; }
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
@@ -107,6 +123,17 @@ public:
return *this;
}
+ LLPointer<Type>& operator =(LLPointer<Type>&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template<typename Subclass>
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
@@ -115,6 +142,18 @@ public:
return *this;
}
+ template<typename Subclass>
+ LLPointer<Type>& operator =(LLPointer<Subclass>&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// Just exchange the pointers, which will not change the reference counts.
static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
{
@@ -141,9 +180,9 @@ protected:
if (mPointer)
{
Type *temp = mPointer;
- mPointer = NULL;
+ mPointer = nullptr;
temp->unref();
- if (mPointer != NULL)
+ if (mPointer != nullptr)
{
LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
unref();
@@ -168,9 +207,11 @@ protected:
template <class Type> class LLConstPointer
{
+ template<typename Subclass>
+ friend class LLConstPointer;
public:
LLConstPointer() :
- mPointer(NULL)
+ mPointer(nullptr)
{
}
@@ -186,6 +227,12 @@ public:
ref();
}
+ LLConstPointer(LLConstPointer<Type>&& ptr) noexcept
+ {
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template<typename Subclass>
LLConstPointer(const LLConstPointer<Subclass>& ptr) :
@@ -194,6 +241,13 @@ public:
ref();
}
+ template<typename Subclass>
+ LLConstPointer(LLConstPointer<Subclass>&& ptr) noexcept :
+ mPointer(ptr.get())
+ {
+ ptr.mPointer = nullptr;
+ }
+
~LLConstPointer()
{
unref();
@@ -203,11 +257,11 @@ public:
const Type* operator->() const { return mPointer; }
const Type& operator*() const { return *mPointer; }
- operator BOOL() const { return (mPointer != NULL); }
- operator bool() const { return (mPointer != NULL); }
- bool operator!() const { return (mPointer == NULL); }
- bool isNull() const { return (mPointer == NULL); }
- bool notNull() const { return (mPointer != NULL); }
+ operator BOOL() const { return (mPointer != nullptr); }
+ operator bool() const { return (mPointer != nullptr); }
+ bool operator!() const { return (mPointer == nullptr); }
+ bool isNull() const { return (mPointer == nullptr); }
+ bool notNull() const { return (mPointer != nullptr); }
operator const Type*() const { return mPointer; }
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
@@ -239,6 +293,17 @@ public:
return *this;
}
+ LLConstPointer<Type>& operator =(LLConstPointer<Type>&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template<typename Subclass>
LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
@@ -252,6 +317,18 @@ public:
return *this;
}
+ template<typename Subclass>
+ LLConstPointer<Type>& operator =(LLConstPointer<Subclass>&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// Just exchange the pointers, which will not change the reference counts.
static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)
{
@@ -278,9 +355,9 @@ protected:
if (mPointer)
{
const Type *temp = mPointer;
- mPointer = NULL;
+ mPointer = nullptr;
temp->unref();
- if (mPointer != NULL)
+ if (mPointer != nullptr)
{
LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
unref();
@@ -313,7 +390,7 @@ public:
: LLPointer<Type>(ptr),
mStayUnique(false)
{
- if (ptr.mForceUnique)
+ if (ptr.mStayUnique)
{
makeUnique();
}
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 0248e8f8b9..a528cc7fd8 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -74,9 +74,6 @@
#ifndef LL_MSVC
#define LL_MSVC 1
#endif
- #if _MSC_VER < 1400
- #define LL_MSVC7 //Visual C++ 2003 or earlier
- #endif
#endif
// Deal with minor differences on Unixy OSes.
@@ -130,8 +127,6 @@
#endif
// level 4 warnings that we need to disable:
-#pragma warning (disable : 4244) // possible loss of data on conversions
-#pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class
#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class
#endif // LL_MSVC
diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h
index 722d9afca2..732436cc4f 100644
--- a/indra/llcommon/llprofiler.h
+++ b/indra/llcommon/llprofiler.h
@@ -84,7 +84,7 @@ extern thread_local bool gProfilerEnabled;
// #define TRACY_NO_BROADCAST 1
// #define TRACY_ONLY_LOCALHOST 1
#define TRACY_ONLY_IPV4 1
- #include "Tracy.hpp"
+ #include "tracy/Tracy.hpp"
// Enable OpenGL profiling
#define LL_PROFILER_ENABLE_TRACY_OPENGL 0
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 7d77f6f6a9..1c4ac5a7bf 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -483,7 +483,7 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
if (sleep_time.count() > 0)
{
- ms_sleep(sleep_time.count());
+ ms_sleep((U32)sleep_time.count());
}
}
processRequest(req);
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
index 25d75af568..2c51e6f07f 100644
--- a/indra/llcommon/llrand.cpp
+++ b/indra/llcommon/llrand.cpp
@@ -85,7 +85,7 @@ inline F32 ll_internal_random<F32>()
// Per Monty, it's important to clamp using the correct fmodf() rather
// than expanding to F64 for fmod() and then truncating back to F32. Prior
// to this change, we were getting sporadic ll_frand() == 1.0 results.
- F32 rv{ narrow<F32>(gRandomGenerator()) };
+ F32 rv{ narrow<F64>(gRandomGenerator()) };
if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f);
return rv;
}
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 663ceac22b..77fe545c3f 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -30,6 +30,7 @@
#include "linden_common.h"
#include "llsd.h"
+#include "llbase64.h"
#include "llerror.h"
#include "../llmath/llmath.h"
#include "llformat.h"
@@ -105,6 +106,9 @@ public:
static void reset(Impl*& var, Impl* impl);
///< safely set var to refer to the new impl (possibly shared)
+ static void move(Impl*& var, Impl*& impl);
+ ///< safely move impl from one object to another
+
static Impl& safe( Impl*);
static const Impl& safe(const Impl*);
///< since a NULL Impl* is used for undefined, this ensures there is
@@ -122,11 +126,17 @@ public:
virtual void assign(Impl*& var, LLSD::Boolean);
virtual void assign(Impl*& var, LLSD::Integer);
virtual void assign(Impl*& var, LLSD::Real);
+ virtual void assign(Impl*& var, const char*);
virtual void assign(Impl*& var, const LLSD::String&);
virtual void assign(Impl*& var, const LLSD::UUID&);
virtual void assign(Impl*& var, const LLSD::Date&);
virtual void assign(Impl*& var, const LLSD::URI&);
virtual void assign(Impl*& var, const LLSD::Binary&);
+ virtual void assign(Impl*& var, LLSD::String&&);
+ virtual void assign(Impl*& var, LLSD::UUID&&);
+ virtual void assign(Impl*& var, LLSD::Date&&);
+ virtual void assign(Impl*& var, LLSD::URI&&);
+ virtual void assign(Impl*& var, LLSD::Binary&&);
///< If the receiver is the right type and unshared, these are simple
// data assignments, othewise the default implementation handless
// constructing the proper Impl subclass
@@ -142,11 +152,13 @@ public:
virtual const String& asStringRef() const { static const std::string empty; return empty; }
- virtual bool has(const String&) const { return false; }
- virtual LLSD get(const String&) const { return LLSD(); }
+ virtual String asXMLRPCValue() const { return "<nil/>"; }
+
+ virtual bool has(std::string_view) const { return false; }
+ virtual LLSD get(std::string_view) const { return LLSD(); }
virtual LLSD getKeys() const { return LLSD::emptyArray(); }
virtual void erase(const String&) { }
- virtual const LLSD& ref(const String&) const{ return undef(); }
+ virtual const LLSD& ref(std::string_view) const{ return undef(); }
virtual size_t size() const { return 0; }
virtual LLSD get(size_t) const { return LLSD(); }
@@ -182,7 +194,7 @@ namespace LLSDUnnamedNamespace
namespace
#endif
{
- template<LLSD::Type T, class Data, class DataRef = Data>
+ template<LLSD::Type T, class Data, class DataRef = Data, class DataMove = Data>
class ImplBase : public LLSD::Impl
///< This class handles most of the work for a subclass of Impl
// for a given simple data type. Subclasses of this provide the
@@ -195,6 +207,7 @@ namespace
public:
ImplBase(DataRef value) : mValue(value) { }
+ ImplBase(DataMove value) : mValue(std::move(value)) { }
virtual LLSD::Type type() const { return T; }
@@ -209,11 +222,21 @@ namespace
mValue = value;
}
}
+ virtual void assign(LLSD::Impl*& var, DataMove value) {
+ if (shared())
+ {
+ Impl::assign(var, std::move(value));
+ }
+ else
+ {
+ mValue = std::move(value);
+ }
+ }
};
- class ImplBoolean
- : public ImplBase<LLSD::TypeBoolean, LLSD::Boolean>
+ class ImplBoolean final
+ : public ImplBase<LLSD::TypeBoolean, LLSD::Boolean, LLSD::Boolean, LLSD::Boolean&&>
{
public:
ImplBoolean(LLSD::Boolean v) : Base(v) { }
@@ -222,6 +245,8 @@ namespace
virtual LLSD::Integer asInteger() const { return mValue ? 1 : 0; }
virtual LLSD::Real asReal() const { return mValue ? 1 : 0; }
virtual LLSD::String asString() const;
+
+ virtual LLSD::String asXMLRPCValue() const { return mValue ? "<boolean>1</boolean>" : "<boolean>0</boolean>"; }
};
LLSD::String ImplBoolean::asString() const
@@ -233,8 +258,8 @@ namespace
{ return mValue ? "true" : ""; }
- class ImplInteger
- : public ImplBase<LLSD::TypeInteger, LLSD::Integer>
+ class ImplInteger final
+ : public ImplBase<LLSD::TypeInteger, LLSD::Integer, LLSD::Integer, LLSD::Integer&&>
{
public:
ImplInteger(LLSD::Integer v) : Base(v) { }
@@ -243,14 +268,16 @@ namespace
virtual LLSD::Integer asInteger() const { return mValue; }
virtual LLSD::Real asReal() const { return mValue; }
virtual LLSD::String asString() const;
+
+ virtual LLSD::String asXMLRPCValue() const { return "<int>" + std::to_string(mValue) + "</int>"; }
};
LLSD::String ImplInteger::asString() const
{ return llformat("%d", mValue); }
- class ImplReal
- : public ImplBase<LLSD::TypeReal, LLSD::Real>
+ class ImplReal final
+ : public ImplBase<LLSD::TypeReal, LLSD::Real, LLSD::Real, LLSD::Real&&>
{
public:
ImplReal(LLSD::Real v) : Base(v) { }
@@ -259,6 +286,8 @@ namespace
virtual LLSD::Integer asInteger() const;
virtual LLSD::Real asReal() const { return mValue; }
virtual LLSD::String asString() const;
+
+ virtual LLSD::String asXMLRPCValue() const { return "<double>" + std::to_string(mValue) + "</double>"; }
};
LLSD::Boolean ImplReal::asBoolean() const
@@ -271,11 +300,12 @@ namespace
{ return llformat("%lg", mValue); }
- class ImplString
- : public ImplBase<LLSD::TypeString, LLSD::String, const LLSD::String&>
+ class ImplString final
+ : public ImplBase<LLSD::TypeString, LLSD::String, const LLSD::String&, LLSD::String&&>
{
public:
ImplString(const LLSD::String& v) : Base(v) { }
+ ImplString(LLSD::String&& v) : Base(std::move(v)) {}
virtual LLSD::Boolean asBoolean() const { return !mValue.empty(); }
virtual LLSD::Integer asInteger() const;
@@ -286,9 +316,24 @@ namespace
virtual LLSD::URI asURI() const { return LLURI(mValue); }
virtual size_t size() const { return mValue.size(); }
virtual const LLSD::String& asStringRef() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "<string>" + LLStringFn::xml_encode(mValue) + "</string>"; }
+
+ using LLSD::Impl::assign; // Unhiding base class virtuals...
+ virtual void assign(LLSD::Impl*& var, const char* value)
+ {
+ if (shared())
+ {
+ Impl::assign(var, value);
+ }
+ else
+ {
+ mValue = value;
+ }
+ }
};
- LLSD::Integer ImplString::asInteger() const
+ LLSD::Integer ImplString::asInteger() const
{
// This must treat "1.23" not as an error, but as a number, which is
// then truncated down to an integer. Hence, this code doesn't call
@@ -298,7 +343,7 @@ namespace
return (int)asReal();
}
- LLSD::Real ImplString::asReal() const
+ LLSD::Real ImplString::asReal() const
{
F64 v = 0.0;
std::istringstream i_stream(mValue);
@@ -315,25 +360,32 @@ namespace
}
- class ImplUUID
- : public ImplBase<LLSD::TypeUUID, LLSD::UUID, const LLSD::UUID&>
+ class ImplUUID final
+ : public ImplBase<LLSD::TypeUUID, LLSD::UUID, const LLSD::UUID&, LLSD::UUID&&>
{
public:
ImplUUID(const LLSD::UUID& v) : Base(v) { }
+ ImplUUID(LLSD::UUID&& v) : Base(std::move(v)) { }
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::UUID asUUID() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "<string>" + mValue.asString() + "</string>"; }
};
- class ImplDate
- : public ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>
+ class ImplDate final
+ : public ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&, LLSD::Date&&>
{
public:
ImplDate(const LLSD::Date& v)
- : ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v)
+ : ImplBase(v)
{ }
+ ImplDate(LLSD::Date&& v)
+ : ImplBase(std::move(v))
+ { }
+
virtual LLSD::Integer asInteger() const
{
return (LLSD::Integer)(mValue.secondsSinceEpoch());
@@ -344,34 +396,42 @@ namespace
}
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::Date asDate() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "<dateTime.iso8601>" + mValue.toHTTPDateString("%FT%T") + "</dateTime.iso8601>"; }
};
- class ImplURI
- : public ImplBase<LLSD::TypeURI, LLSD::URI, const LLSD::URI&>
+ class ImplURI final
+ : public ImplBase<LLSD::TypeURI, LLSD::URI, const LLSD::URI&, LLSD::URI&&>
{
public:
ImplURI(const LLSD::URI& v) : Base(v) { }
+ ImplURI(LLSD::URI&& v) : Base(std::move(v)) { }
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::URI asURI() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "<string>" + LLStringFn::xml_encode(mValue.asString()) + "</string>"; }
};
- class ImplBinary
- : public ImplBase<LLSD::TypeBinary, LLSD::Binary, const LLSD::Binary&>
+ class ImplBinary final
+ : public ImplBase<LLSD::TypeBinary, LLSD::Binary, const LLSD::Binary&, LLSD::Binary&&>
{
public:
ImplBinary(const LLSD::Binary& v) : Base(v) { }
+ ImplBinary(LLSD::Binary&& v) : Base(std::move(v)) { }
virtual const LLSD::Binary& asBinary() const{ return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "<base64>" + LLBase64::encode(mValue.data(), mValue.size()) + "</base64>"; }
};
- class ImplMap : public LLSD::Impl
+ class ImplMap final : public LLSD::Impl
{
private:
- typedef std::map<LLSD::String, LLSD> DataMap;
+ typedef std::map<LLSD::String, LLSD, std::less<>> DataMap;
DataMap mData;
@@ -387,17 +447,30 @@ namespace
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
- virtual bool has(const LLSD::String&) const;
+ virtual LLSD::String asXMLRPCValue() const
+ {
+ std::ostringstream os;
+ os << "<struct>";
+ for (const auto& it : mData)
+ {
+ os << "<member><name>" << LLStringFn::xml_encode(it.first) << "</name>"
+ << it.second.asXMLRPCValue() << "</member>";
+ }
+ os << "</struct>";
+ return os.str();
+ }
+
+ virtual bool has(std::string_view) const;
using LLSD::Impl::get; // Unhiding get(size_t)
using LLSD::Impl::erase; // Unhiding erase(size_t)
using LLSD::Impl::ref; // Unhiding ref(size_t)
- virtual LLSD get(const LLSD::String&) const;
+ virtual LLSD get(std::string_view) const;
virtual LLSD getKeys() const;
- void insert(const LLSD::String& k, const LLSD& v);
+ void insert(std::string_view k, const LLSD& v);
virtual void erase(const LLSD::String&);
- LLSD& ref(const LLSD::String&);
- virtual const LLSD& ref(const LLSD::String&) const;
+ LLSD& ref(std::string_view);
+ virtual const LLSD& ref(std::string_view) const;
virtual size_t size() const { return mData.size(); }
@@ -425,14 +498,14 @@ namespace
}
}
- bool ImplMap::has(const LLSD::String& k) const
+ bool ImplMap::has(const std::string_view k) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
DataMap::const_iterator i = mData.find(k);
return i != mData.end();
}
- LLSD ImplMap::get(const LLSD::String& k) const
+ LLSD ImplMap::get(const std::string_view k) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
DataMap::const_iterator i = mData.find(k);
@@ -452,10 +525,10 @@ namespace
return keys;
}
- void ImplMap::insert(const LLSD::String& k, const LLSD& v)
+ void ImplMap::insert(std::string_view k, const LLSD& v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
- mData.insert(DataMap::value_type(k, v));
+ mData.emplace(k, v);
}
void ImplMap::erase(const LLSD::String& k)
@@ -464,15 +537,21 @@ namespace
mData.erase(k);
}
- LLSD& ImplMap::ref(const LLSD::String& k)
+ LLSD& ImplMap::ref(std::string_view k)
{
- return mData[k];
+ DataMap::iterator i = mData.lower_bound(k);
+ if (i == mData.end() || mData.key_comp()(k, i->first))
+ {
+ return mData.emplace_hint(i, std::make_pair(k, LLSD()))->second;
+ }
+
+ return i->second;
}
- const LLSD& ImplMap::ref(const LLSD::String& k) const
+ const LLSD& ImplMap::ref(std::string_view k) const
{
DataMap::const_iterator i = mData.lower_bound(k);
- if (i == mData.end() || mData.key_comp()(k, i->first))
+ if (i == mData.end() || mData.key_comp()(k, i->first))
{
return undef();
}
@@ -500,7 +579,7 @@ namespace
{
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
Impl::calcStats((*iter).second, type_counts, share_counts);
- iter++;
+ ++iter;
}
// Add in the values for this map
@@ -511,7 +590,7 @@ namespace
class ImplArray : public LLSD::Impl
{
private:
- typedef std::vector<LLSD> DataVector;
+ typedef std::vector<LLSD> DataVector;
DataVector mData;
@@ -527,6 +606,18 @@ namespace
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
+ virtual LLSD::String asXMLRPCValue() const
+ {
+ std::ostringstream os;
+ os << "<array><data>";
+ for (const auto& it : mData)
+ {
+ os << it.asXMLRPCValue();
+ }
+ os << "</data></array>";
+ return os.str();
+ }
+
using LLSD::Impl::get; // Unhiding get(LLSD::String)
using LLSD::Impl::erase; // Unhiding erase(LLSD::String)
using LLSD::Impl::ref; // Unhiding ref(LLSD::String)
@@ -647,7 +738,7 @@ namespace
while (iter != endArray())
{ // Add values for all items held in the array
Impl::calcStats((*iter), type_counts, share_counts);
- iter++;
+ ++iter;
}
// Add in the values for this array
@@ -685,6 +776,16 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl)
var = impl;
}
+void LLSD::Impl::move(Impl*& var, Impl*& impl)
+{
+ if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0)
+ {
+ delete var; // destroy var if usage falls to 0 and not static
+ }
+ var = impl; // Steal impl to var without incrementing use since this is a move
+ impl = nullptr; // null out old-impl pointer
+}
+
LLSD::Impl& LLSD::Impl::safe(Impl* impl)
{
static Impl theUndefined(STATIC_USAGE_COUNT);
@@ -738,6 +839,11 @@ void LLSD::Impl::assign(Impl*& var, LLSD::Real v)
reset(var, new ImplReal(v));
}
+void LLSD::Impl::assign(Impl*& var, const char* v)
+{
+ reset(var, new ImplString(v));
+}
+
void LLSD::Impl::assign(Impl*& var, const LLSD::String& v)
{
reset(var, new ImplString(v));
@@ -763,6 +869,31 @@ void LLSD::Impl::assign(Impl*& var, const LLSD::Binary& v)
reset(var, new ImplBinary(v));
}
+void LLSD::Impl::assign(Impl*& var, LLSD::String&& v)
+{
+ reset(var, new ImplString(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::UUID&& v)
+{
+ reset(var, new ImplUUID(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::Date&& v)
+{
+ reset(var, new ImplDate(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::URI&& v)
+{
+ reset(var, new ImplURI(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::Binary&& v)
+{
+ reset(var, new ImplBinary(std::move(v)));
+}
+
const LLSD& LLSD::Impl::undef()
{
@@ -835,6 +966,9 @@ LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0)
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
+LLSD::LLSD(LLSD&& other) noexcept : impl(nullptr) { ALLOC_LLSD_OBJECT; Impl::move(impl, other.impl); }
+void LLSD::assign(LLSD&& other) { Impl::move(impl, other.impl); }
+LLSD& LLSD::operator=(LLSD&& other) noexcept { Impl::move(impl, other.impl); return *this; }
void LLSD::clear() { Impl::assignUndefined(impl); }
@@ -849,6 +983,11 @@ LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(UUID&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(String&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(Date&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(URI&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(Binary&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
// Scalar Assignment
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
@@ -859,6 +998,11 @@ void LLSD::assign(const UUID& v) { safe(impl).assign(impl, v); }
void LLSD::assign(const Date& v) { safe(impl).assign(impl, v); }
void LLSD::assign(const URI& v) { safe(impl).assign(impl, v); }
void LLSD::assign(const Binary& v) { safe(impl).assign(impl, v); }
+void LLSD::assign(String&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(UUID&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(Date&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(URI&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(Binary&& v) { safe(impl).assign(impl, std::move(v)); }
// Scalar Accessors
LLSD::Boolean LLSD::asBoolean() const { return safe(impl).asBoolean(); }
@@ -872,11 +1016,13 @@ const LLSD::Binary& LLSD::asBinary() const { return safe(impl).asBinary(); }
const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
+LLSD::String LLSD::asXMLRPCValue() const { return "<value>" + safe(impl).asXMLRPCValue() + "</value>"; }
+
// const char * helpers
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
void LLSD::assign(const char* v)
{
- if(v) assign(std::string(v));
+ if(v) safe(impl).assign(impl, v);
else assign(std::string());
}
@@ -888,24 +1034,24 @@ LLSD LLSD::emptyMap()
return v;
}
-bool LLSD::has(const String& k) const { return safe(impl).has(k); }
-LLSD LLSD::get(const String& k) const { return safe(impl).get(k); }
+bool LLSD::has(const std::string_view k) const { return safe(impl).has(k); }
+LLSD LLSD::get(const std::string_view k) const { return safe(impl).get(k); }
LLSD LLSD::getKeys() const { return safe(impl).getKeys(); }
-void LLSD::insert(const String& k, const LLSD& v) { makeMap(impl).insert(k, v); }
+void LLSD::insert(std::string_view k, const LLSD& v) { makeMap(impl).insert(k, v); }
-LLSD& LLSD::with(const String& k, const LLSD& v)
+LLSD& LLSD::with(std::string_view k, const LLSD& v)
{
makeMap(impl).insert(k, v);
return *this;
}
void LLSD::erase(const String& k) { makeMap(impl).erase(k); }
-LLSD& LLSD::operator[](const String& k)
+LLSD& LLSD::operator[](const std::string_view k)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
return makeMap(impl).ref(k);
}
-const LLSD& LLSD::operator[](const String& k) const
+const LLSD& LLSD::operator[](const std::string_view k) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
return safe(impl).ref(k);
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index a5e735b561..d2b3548831 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -161,6 +161,13 @@ public:
//@}
+ /** @name Movable */
+ //@{
+ LLSD(LLSD&& other) noexcept;
+ void assign(LLSD&& other);
+ LLSD& operator=(LLSD&& other) noexcept;
+ //@}
+
void clear(); ///< resets to Undefined
@@ -188,6 +195,11 @@ public:
LLSD(const Date&);
LLSD(const URI&);
LLSD(const Binary&);
+ LLSD(String&&);
+ LLSD(UUID&&);
+ LLSD(Date&&);
+ LLSD(URI&&);
+ LLSD(Binary&&);
//@}
/** @name Convenience Constructors */
@@ -215,6 +227,11 @@ public:
void assign(const Date&);
void assign(const URI&);
void assign(const Binary&);
+ void assign(String&&);
+ void assign(UUID&&);
+ void assign(Date&&);
+ void assign(URI&&);
+ void assign(Binary&&);
LLSD& operator=(Boolean v) { assign(v); return *this; }
LLSD& operator=(Integer v) { assign(v); return *this; }
@@ -224,6 +241,11 @@ public:
LLSD& operator=(const Date& v) { assign(v); return *this; }
LLSD& operator=(const URI& v) { assign(v); return *this; }
LLSD& operator=(const Binary& v) { assign(v); return *this; }
+ LLSD& operator=(String&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(UUID&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(Date&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(URI&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(Binary&& v) { assign(std::move(v)); return *this; }
//@}
/**
@@ -259,10 +281,14 @@ public:
UUID asUUID() const;
Date asDate() const;
URI asURI() const;
- const Binary& asBinary() const;
+ const Binary& asBinary() const;
// asStringRef on any non-string type will return a ref to an empty string.
- const String& asStringRef() const;
+ const String& asStringRef() const;
+
+ // Return "<value><((type))>((scalar value or recursive calls))</((type))></value>"
+ // See http://xmlrpc.com/spec.md
+ String asXMLRPCValue() const;
operator Boolean() const { return asBoolean(); }
operator Integer() const { return asInteger(); }
@@ -275,7 +301,7 @@ public:
// This is needed because most platforms do not automatically
// convert the boolean negation as a bool in an if statement.
- bool operator!() const {return !asBoolean();}
+ bool operator!() const { return !asBoolean(); }
//@}
/** @name Character Pointer Helpers
@@ -292,24 +318,22 @@ public:
//@{
static LLSD emptyMap();
- bool has(const String&) const;
- LLSD get(const String&) const;
+ bool has(const std::string_view) const;
+ LLSD get(const std::string_view) const;
LLSD getKeys() const; // Return an LLSD array with keys as strings
- void insert(const String&, const LLSD&);
+ void insert(std::string_view, const LLSD&);
void erase(const String&);
- LLSD& with(const String&, const LLSD&);
+ LLSD& with(std::string_view, const LLSD&);
- LLSD& operator[](const String&);
+ LLSD& operator[](const std::string_view);
LLSD& operator[](const char* c)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
- return (*this)[String(c)];
+ return c ? (*this)[std::string_view(c)] : *this;
}
- const LLSD& operator[](const String&) const;
+ const LLSD& operator[](const std::string_view) const;
const LLSD& operator[](const char* c) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
- return (*this)[String(c)];
+ return c ? (*this)[std::string_view(c)] : *this;
}
//@}
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index b981be4d0a..3ae153a67c 100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -149,7 +149,7 @@ bool LLParamSDParser::readF32(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
- *((F32*)val_ptr) = self.mCurReadSD->asReal();
+ *((F32*)val_ptr) = (F32)self.mCurReadSD->asReal();
return true;
}
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 15002580c9..37af366a20 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -231,7 +231,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, llssize max_bytes)
}
// Since we've already read 'inbuf' bytes into 'hdr_buf', prepend that
// data to whatever remains in 'str'.
- LLMemoryStreamBuf already(reinterpret_cast<const U8*>(hdr_buf), inbuf);
+ LLMemoryStreamBuf already(reinterpret_cast<const U8*>(hdr_buf), (S32)inbuf);
cat_streambuf prebuff(&already, str.rdbuf());
std::istream prepend(&prebuff);
#if 1
@@ -475,7 +475,7 @@ LLSDNotationParser::~LLSDNotationParser()
// virtual
S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// map: { string:object, string:object }
// array: [ object, object, object ]
// undef: !
@@ -566,7 +566,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
data,
NOTATION_FALSE_SERIAL,
false);
- if(PARSE_FAILURE == cnt) parse_count = cnt;
+ if(PARSE_FAILURE == cnt) parse_count = (S32)cnt;
else account(cnt);
}
else
@@ -592,7 +592,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
if(isalpha(c))
{
auto cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true);
- if(PARSE_FAILURE == cnt) parse_count = cnt;
+ if(PARSE_FAILURE == cnt) parse_count = (S32)cnt;
else account(cnt);
}
else
@@ -735,7 +735,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// map: { string:object, string:object }
map = LLSD::emptyMap();
S32 parse_count = 0;
@@ -796,7 +796,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) c
S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// array: [ object, object, object ]
array = LLSD::emptyArray();
S32 parse_count = 0;
@@ -836,7 +836,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_dept
bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
std::string value;
auto count = deserialize_string(istr, value, mMaxBytesLeft);
if(PARSE_FAILURE == count) return false;
@@ -847,7 +847,7 @@ bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// binary: b##"ff3120ab1"
// or: b(len)"..."
@@ -950,7 +950,7 @@ LLSDBinaryParser::~LLSDBinaryParser()
// virtual
S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
/**
* Undefined: '!'<br>
* Boolean: '1' for true '0' for false<br>
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 88cbb3b984..6396caf8d5 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -554,7 +554,7 @@ void LLSDXMLParser::Impl::parsePart(const char* buf, llssize len)
if ( buf != NULL
&& len > 0 )
{
- XML_Status status = XML_Parse(mParser, buf, len, false);
+ XML_Status status = XML_Parse(mParser, buf, (int)len, 0);
if (status == XML_STATUS_ERROR)
{
LL_INFOS() << "Unexpected XML parsing error at start" << LL_ENDL;
@@ -930,7 +930,7 @@ void LLSDXMLParser::parsePart(const char *buf, llssize len)
// virtual
S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
#ifdef XML_PARSER_PERFORMANCE_TESTS
XML_Timer timer( &parseTime );
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index dd3a58c26d..12f67208c1 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -51,7 +51,7 @@
// U32
LLSD ll_sd_from_U32(const U32 val)
{
- std::vector<U8> v;
+ LLSD::Binary v;
U32 net_order = htonl(val);
v.resize(4);
@@ -63,7 +63,7 @@ LLSD ll_sd_from_U32(const U32 val)
U32 ll_U32_from_sd(const LLSD& sd)
{
U32 ret;
- std::vector<U8> v = sd.asBinary();
+ const LLSD::Binary& v = sd.asBinary();
if (v.size() < 4)
{
return 0;
@@ -76,7 +76,7 @@ U32 ll_U32_from_sd(const LLSD& sd)
//U64
LLSD ll_sd_from_U64(const U64 val)
{
- std::vector<U8> v;
+ LLSD::Binary v;
U32 high, low;
high = (U32)(val >> 32);
@@ -94,7 +94,7 @@ LLSD ll_sd_from_U64(const U64 val)
U64 ll_U64_from_sd(const LLSD& sd)
{
U32 high, low;
- std::vector<U8> v = sd.asBinary();
+ const LLSD::Binary& v = sd.asBinary();
if (v.size() < 8)
{
@@ -112,7 +112,7 @@ U64 ll_U64_from_sd(const LLSD& sd)
// IP Address (stored in net order in a U32, so don't need swizzling)
LLSD ll_sd_from_ipaddr(const U32 val)
{
- std::vector<U8> v;
+ LLSD::Binary v;
v.resize(4);
memcpy(&(v[0]), &val, 4); /* Flawfinder: ignore */
@@ -123,7 +123,7 @@ LLSD ll_sd_from_ipaddr(const U32 val)
U32 ll_ipaddr_from_sd(const LLSD& sd)
{
U32 ret;
- std::vector<U8> v = sd.asBinary();
+ const LLSD::Binary& v = sd.asBinary();
if (v.size() < 4)
{
return 0;
@@ -135,17 +135,17 @@ U32 ll_ipaddr_from_sd(const LLSD& sd)
// Converts an LLSD binary to an LLSD string
LLSD ll_string_from_binary(const LLSD& sd)
{
- std::vector<U8> value = sd.asBinary();
+ const LLSD::Binary& value = sd.asBinary();
std::string str;
str.resize(value.size());
- memcpy(&str[0], &value[0], value.size());
+ memcpy(&str[0], value.data(), value.size());
return str;
}
// Converts an LLSD string to an LLSD binary
LLSD ll_binary_from_string(const LLSD& sd)
{
- std::vector<U8> binary_value;
+ LLSD::Binary binary_value;
std::string string_value = sd.asString();
for (const U8 c : string_value)
@@ -214,7 +214,7 @@ bool compare_llsd_with_template(
const LLSD& template_llsd,
LLSD& resultant_llsd)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
if (
llsd_to_test.isUndefined() &&
@@ -337,7 +337,7 @@ bool filter_llsd_with_template(
const LLSD & template_llsd,
LLSD & resultant_llsd)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
if (llsd_to_test.isUndefined() && template_llsd.isDefined())
{
@@ -533,7 +533,7 @@ class TypeLookup
public:
TypeLookup()
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di)
{
@@ -543,7 +543,7 @@ public:
std::string lookup(LLSD::Type type) const
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
MapType::const_iterator found = mMap.find(type);
if (found != mMap.end())
@@ -595,7 +595,7 @@ static std::string match_types(LLSD::Type expect, // prototype.type()
LLSD::Type actual, // type we're checking
const std::string& pfx) // as for llsd_matches
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// Trivial case: if the actual type is exactly what we expect, we're good.
if (actual == expect)
@@ -634,7 +634,7 @@ static std::string match_types(LLSD::Type expect, // prototype.type()
// see docstring in .h file
std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// An undefined prototype means that any data is valid.
// An undefined slot in an array or map prototype means that any data
@@ -768,7 +768,7 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str
bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// We're comparing strict equality of LLSD representation rather than
// performing any conversions. So if the types aren't equal, the LLSD
@@ -878,7 +878,7 @@ namespace llsd
LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// Treat rawPath uniformly as an array. If it's not already an array,
// store it as the only entry in one. (But let's say Undefined means an
@@ -905,7 +905,7 @@ LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
// path entry that's bad.
for (LLSD::Integer i = 0; i < path.size(); ++i)
{
- LL_PROFILE_ZONE_NUM( i )
+ LL_PROFILE_ZONE_NUM(i);
const LLSD& key{path[i]};
if (key.isString())
@@ -935,7 +935,7 @@ LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
LLSD drill(const LLSD& blob, const LLSD& path)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// drill_ref() does exactly what we want. Temporarily cast away
// const-ness and use that.
@@ -949,7 +949,7 @@ LLSD drill(const LLSD& blob, const LLSD& path)
// filter may be include to exclude/include keys in a map.
LLSD llsd_clone(LLSD value, LLSD filter)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
LLSD clone;
bool has_filter(filter.isMap());
@@ -990,8 +990,7 @@ LLSD llsd_clone(LLSD value, LLSD filter)
case LLSD::TypeBinary:
{
- LLSD::Binary bin(value.asBinary().begin(), value.asBinary().end());
- clone = LLSD::Binary(bin);
+ clone = LLSD::Binary(value.asBinary().begin(), value.asBinary().end());
break;
}
default:
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 7c6be25309..316831cd74 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -37,7 +37,8 @@
#include "llmainthreadtask.h"
#ifdef LL_WINDOWS
-#pragma warning( disable : 4506 ) // no definition for inline function
+#pragma warning(push)
+#pragma warning(disable : 4506) // no definition for inline function
#endif
class LLSingletonBase: private boost::noncopyable
@@ -861,4 +862,8 @@ private:
template <class T>
T* LLSimpleton<T>::sInstance{ nullptr };
+#ifdef LL_WINDOWS
+#pragma warning(pop)
+#endif
+
#endif
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 1b52d94258..7d41c42ba7 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -226,11 +226,11 @@ void delete_and_clear_array(T*& ptr)
// foo[2] = "hello";
// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
-template <typename K, typename T>
-inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key)
+template <typename T>
+inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_type const& key)
{
// Typedef here avoids warnings because of new c++ naming rules.
- typedef typename std::map<K,T*>::const_iterator map_iter;
+ typedef typename T::const_iterator map_iter;
map_iter iter = inmap.find(key);
if(iter == inmap.end())
{
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 514d73b24b..c57f8b1e96 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -250,7 +250,7 @@ LLWString utf16str_to_wstring(const U16* utf16str, size_t len)
while (i < len)
{
llwchar cur_char;
- i += utf16chars_to_wchar(chars16+i, &cur_char);
+ i += (S32)utf16chars_to_wchar(chars16+i, &cur_char);
wout += cur_char;
}
return wout;
@@ -1208,6 +1208,75 @@ namespace LLStringFn
return output;
}
+ using literals_t = std::map<char, std::string>;
+ static const literals_t xml_elem_literals =
+ {
+ { '<', "&lt;" },
+ { '>', "&gt;" },
+ { '&', "&amp;" }
+ };
+ static const literals_t xml_attr_literals =
+ {
+ { '"', "&quot;" },
+ { '\'', "&apos;" }
+ };
+
+ static void literals_encode(std::string& text, const literals_t& literals)
+ {
+ for (const std::pair<char, std::string> it : literals)
+ {
+ std::string::size_type pos = 0;
+ while ((pos = text.find(it.first, pos)) != std::string::npos)
+ {
+ text.replace(pos, 1, it.second);
+ pos += it.second.size();
+ }
+ }
+ }
+
+ static void literals_decode(std::string& text, const literals_t& literals)
+ {
+ for (const std::pair<char, std::string> it : literals)
+ {
+ std::string::size_type pos = 0;
+ while ((pos = text.find(it.second, pos)) != std::string::npos)
+ {
+ text[pos++] = it.first;
+ text.erase(pos, it.second.size() - 1);
+ }
+ }
+ }
+
+ /**
+ * @brief Replace all characters that are not allowed in XML 1.0
+ * with corresponding literals: [ < > & ] => [ &lt; &gt; &amp; ]
+ */
+ std::string xml_encode(const std::string& input, bool for_attribute)
+ {
+ std::string result(input);
+ literals_encode(result, xml_elem_literals);
+ if (for_attribute)
+ {
+ literals_encode(result, xml_attr_literals);
+ }
+ return result;
+ }
+
+ /**
+ * @brief Replace some of XML literals that are defined in XML 1.0
+ * with corresponding characters: [ &lt; &gt; &amp; ] => [ < > & ]
+ */
+ std::string xml_decode(const std::string& input, bool for_attribute)
+ {
+ std::string result(input);
+ literals_decode(result, xml_elem_literals);
+ if (for_attribute)
+ {
+ literals_decode(result, xml_attr_literals);
+ }
+ return result;
+ }
+
/**
* @brief Replace all control characters (c < 0x20) with replacement in
* string.
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 123f4184b5..b69a068830 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -890,6 +890,20 @@ namespace LLStringFn
/**
+ * @brief Replace all characters that are not allowed in XML 1.0
+ * with corresponding literals: [ < > & ] => [ &lt; &gt; &amp; ]
+ */
+ LL_COMMON_API std::string xml_encode(const std::string& input, bool for_attribute = false);
+
+
+ /**
+ * @brief Replace some of XML literals that are defined in XML 1.0
+ * with corresponding characters: [ &lt; &gt; &amp; ] => [ < > & ]
+ */
+ LL_COMMON_API std::string xml_decode(const std::string& input, bool for_attribute = false);
+
+
+ /**
* @brief Replace all control characters (0 <= c < 0x20) with replacement in
* string. This is safe for utf-8
*
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index cfb05873df..79625ad9f8 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -74,6 +74,8 @@ using namespace llsd;
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
+# include <sys/types.h>
+# include <mach/mach_init.h>
#elif LL_LINUX
# include <errno.h>
# include <sys/utsname.h>
@@ -85,6 +87,7 @@ const char MEMINFO_FILE[] = "/proc/meminfo";
#endif
LLCPUInfo gSysCPU;
+LLMemoryInfo gSysMemory;
// Don't log memory info any more often than this. It also serves as our
// framerate sample size.
@@ -797,33 +800,32 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
}
//static
-void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb)
+void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
#if LL_WINDOWS
// Sigh, this shouldn't be a static method, then we wouldn't have to
// reload this data separately from refresh()
LLSD statsMap(loadStatsMap());
- avail_physical_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
- avail_virtual_mem_kb = (U32Kilobytes)statsMap["Avail Virtual KB"].asInteger();
+ avail_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
#elif LL_DARWIN
- // mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
- // $ vm_stat
- // Mach Virtual Memory Statistics: (page size of 4096 bytes)
- // Pages free: 462078.
- // Pages active: 142010.
- // Pages inactive: 220007.
- // Pages wired down: 159552.
- // "Translation faults": 220825184.
- // Pages copy-on-write: 2104153.
- // Pages zero filled: 167034876.
- // Pages reactivated: 65153.
- // Pageins: 2097212.
- // Pageouts: 41759.
- // Object cache: 841598 hits of 7629869 lookups (11% hit rate)
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ // use host_statistics64 to get memory info
+ vm_statistics64_data_t vmstat;
+ mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
+ mach_port_t host = mach_host_self();
+ vm_size_t page_size;
+ host_page_size(host, &page_size);
+ kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info_t>(&vmstat), &count);
+ if (result == KERN_SUCCESS)
+ {
+ avail_mem_kb = U64Bytes((vmstat.free_count + vmstat.inactive_count) * page_size);
+ }
+ else
+ {
+ avail_mem_kb = (U32Kilobytes)-1;
+ }
#elif LL_LINUX
// mStatsMap is derived from MEMINFO_FILE:
@@ -874,15 +876,14 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32
// DirectMap4k: 434168 kB
// DirectMap2M: 477184 kB
// (could also run 'free', but easier to read a file than run a program)
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ LLSD statsMap(loadStatsMap());
+ avail_mem_kb = (U32Kilobytes)statsMap["MemFree"].asInteger();
#else
//do not know how to collect available memory info for other systems.
//leave it blank here for now.
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ avail_mem_kb = (U32Kilobytes)-1 ;
#endif
}
@@ -928,7 +929,7 @@ LLSD LLMemoryInfo::getStatsMap() const
LLMemoryInfo& LLMemoryInfo::refresh()
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
mStatsMap = loadStatsMap();
LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
@@ -977,7 +978,7 @@ LLSD LLMemoryInfo::loadStatsMap()
// specifically accepts PROCESS_MEMORY_COUNTERS*, and since this is a
// classic-C API, PROCESS_MEMORY_COUNTERS_EX isn't a subclass. Cast the
// pointer.
- GetProcessMemoryInfo(GetCurrentProcess(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));
+ GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmem, sizeof(pmem));
stats.add("Page Fault Count", pmem.PageFaultCount);
stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index f97d49eeb1..827b0dc048 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -134,8 +134,8 @@ public:
static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib.
#endif
- //get the available memory infomation in KiloBytes.
- static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
+ //get the available memory in KiloBytes.
+ static void getAvailableMemoryKB(U32Kilobytes& avail_mem_kb);
// Retrieve a map of memory statistics. The keys of the map are platform-
// dependent. The values are in kilobytes to try to avoid integer overflow.
@@ -169,6 +169,7 @@ bool LL_COMMON_API gunzip_file(const std::string& srcfile, const std::string& ds
// gzip srcfile into dstfile. Returns false on error.
bool LL_COMMON_API gzip_file(const std::string& srcfile, const std::string& dstfile);
+extern LL_COMMON_API LLMemoryInfo gSysMemory;
extern LL_COMMON_API LLCPUInfo gSysCPU;
#endif // LL_LLSYS_H
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index faaaefd561..9eb92ca6a1 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -344,7 +344,7 @@ bool LLThread::runCondition(void)
// Stop thread execution if requested until unpaused.
void LLThread::checkPause()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->lock();
// This is in a while loop because the pthread API allows for spurious wakeups.
@@ -376,20 +376,20 @@ void LLThread::setQuitting()
// static
LLThread::id_t LLThread::currentID()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
return std::this_thread::get_id();
}
// static
void LLThread::yield()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
std::this_thread::yield();
}
void LLThread::wake()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->lock();
if(!shouldSleep())
{
@@ -400,7 +400,7 @@ void LLThread::wake()
void LLThread::wakeLocked()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if(!shouldSleep())
{
mRunCondition->signal();
@@ -409,13 +409,13 @@ void LLThread::wakeLocked()
void LLThread::lockData()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->lock();
}
void LLThread::unlockData()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->unlock();
}
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index a3e871661c..28d6e4e4cc 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -91,7 +91,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
U32 micro_sleep(U64 us, U32 max_yields)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
#if 0
LARGE_INTEGER ft;
ft.QuadPart = -static_cast<S64>(us * 10); // '-' using relative time
@@ -101,7 +101,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
#else
- Sleep(us / 1000);
+ Sleep((DWORD)(us / 1000));
#endif
return 0;
@@ -109,7 +109,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
void ms_sleep(U32 ms)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
micro_sleep(ms * 1000, 0);
}
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index 8741087f3a..dc9a87eb80 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -100,7 +100,7 @@ bool AccumulatorBufferGroup::isCurrent() const
return mCounts.isCurrent();
}
-void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
+void AccumulatorBufferGroup::append(const AccumulatorBufferGroup& other)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
mCounts.addSamples(other.mCounts, SEQUENTIAL);
@@ -109,7 +109,7 @@ void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
mStackTimers.addSamples(other.mStackTimers, SEQUENTIAL);
}
-void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
+void AccumulatorBufferGroup::merge(const AccumulatorBufferGroup& other)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
mCounts.addSamples(other.mCounts, NON_SEQUENTIAL);
@@ -140,7 +140,7 @@ void AccumulatorBufferGroup::sync()
F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const SampleAccumulator& b)
{
- const F64 epsilon = 0.0000001;
+ constexpr F64 epsilon = 0.0000001;
if (a.getSamplingTime() > epsilon && b.getSamplingTime() > epsilon)
{
@@ -170,7 +170,7 @@ F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const Samp
return a.getSumOfSquares();
}
-void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type )
+void SampleAccumulator::addSamples(const SampleAccumulator& other, EBufferAppendType append_type)
{
if (append_type == NON_SEQUENTIAL)
{
@@ -205,7 +205,7 @@ void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppen
}
}
-void SampleAccumulator::reset( const SampleAccumulator* other )
+void SampleAccumulator::reset(const SampleAccumulator* other)
{
mLastValue = other ? other->mLastValue : NaN;
mHasValue = other ? other->mHasValue : false;
@@ -243,7 +243,7 @@ F64 EventAccumulator::mergeSumsOfSquares(const EventAccumulator& a, const EventA
return a.mSumOfSquares;
}
-void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendType append_type )
+void EventAccumulator::addSamples(const EventAccumulator& other, EBufferAppendType append_type)
{
if (other.mNumSamples)
{
@@ -269,12 +269,12 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT
}
}
-void EventAccumulator::reset( const EventAccumulator* other )
+void EventAccumulator::reset(const EventAccumulator* other)
{
mNumSamples = 0;
mSum = 0;
- mMin = F32(NaN);
- mMax = F32(NaN);
+ mMin = NaN;
+ mMax = NaN;
mMean = NaN;
mSumOfSquares = 0;
mLastValue = other ? other->mLastValue : NaN;
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index ba7acf9547..0a2e2bf997 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -39,7 +39,7 @@
namespace LLTrace
{
- const F64 NaN = std::numeric_limits<double>::quiet_NaN();
+ constexpr F64 NaN = std::numeric_limits<double>::quiet_NaN();
enum EBufferAppendType
{
@@ -251,8 +251,8 @@ namespace LLTrace
EventAccumulator()
: mSum(0),
- mMin(F32(NaN)),
- mMax(F32(NaN)),
+ mMin(NaN),
+ mMax(NaN),
mMean(NaN),
mSumOfSquares(0),
mNumSamples(0),
@@ -288,11 +288,11 @@ namespace LLTrace
void sync(F64SecondsImplicit) {}
F64 getSum() const { return mSum; }
- F32 getMin() const { return mMin; }
- F32 getMax() const { return mMax; }
+ F64 getMin() const { return mMin; }
+ F64 getMax() const { return mMax; }
F64 getLastValue() const { return mLastValue; }
F64 getMean() const { return mMean; }
- F64 getStandardDeviation() const { return sqrtf(mSumOfSquares / mNumSamples); }
+ F64 getStandardDeviation() const { return sqrt(mSumOfSquares / mNumSamples); }
F64 getSumOfSquares() const { return mSumOfSquares; }
S32 getSampleCount() const { return mNumSamples; }
bool hasValue() const { return mNumSamples > 0; }
@@ -307,7 +307,7 @@ namespace LLTrace
F64 mMean,
mSumOfSquares;
- F32 mMin,
+ F64 mMin,
mMax;
S32 mNumSamples;
@@ -322,8 +322,8 @@ namespace LLTrace
SampleAccumulator()
: mSum(0),
- mMin(F32(NaN)),
- mMax(F32(NaN)),
+ mMin(NaN),
+ mMax(NaN),
mMean(NaN),
mSumOfSquares(0),
mLastSampleTimeStamp(0),
@@ -378,11 +378,11 @@ namespace LLTrace
}
F64 getSum() const { return mSum; }
- F32 getMin() const { return mMin; }
- F32 getMax() const { return mMax; }
+ F64 getMin() const { return mMin; }
+ F64 getMax() const { return mMax; }
F64 getLastValue() const { return mLastValue; }
F64 getMean() const { return mMean; }
- F64 getStandardDeviation() const { return sqrtf(mSumOfSquares / mTotalSamplingTime); }
+ F64 getStandardDeviation() const { return sqrt(mSumOfSquares / mTotalSamplingTime); }
F64 getSumOfSquares() const { return mSumOfSquares; }
F64SecondsImplicit getSamplingTime() const { return mTotalSamplingTime; }
S32 getSampleCount() const { return mNumSamples; }
@@ -402,7 +402,7 @@ namespace LLTrace
mLastSampleTimeStamp,
mTotalSamplingTime;
- F32 mMin,
+ F64 mMin,
mMax;
S32 mNumSamples;
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 1ec83be7cb..c23adca7e8 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -229,7 +229,7 @@ F32 Recording::getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& s
update();
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL;
- return (F32)(accumulator.mCalls + (active_accumulator ? active_accumulator->mCalls : 0)) / mElapsedSeconds.value();
+ return (F32)(accumulator.mCalls + (active_accumulator ? active_accumulator->mCalls : 0)) / (F32)mElapsedSeconds.value();
}
bool Recording::hasValue(const StatType<CountAccumulator>& stat)
@@ -296,11 +296,11 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
if (active_accumulator && active_accumulator->hasValue())
{
- F32 t = 0.0f;
+ F64 t = 0.0;
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
if (div > 0)
{
- t = active_accumulator->getSampleCount() / div;
+ t = (F64)active_accumulator->getSampleCount() / (F64)div;
}
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
}
@@ -319,7 +319,7 @@ F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
if (active_accumulator && active_accumulator->hasValue())
{
F64 sum_of_squares = SampleAccumulator::mergeSumsOfSquares(accumulator, *active_accumulator);
- return sqrtf(sum_of_squares / (accumulator.getSamplingTime() + active_accumulator->getSamplingTime()));
+ return sqrt(sum_of_squares / (F64)(accumulator.getSamplingTime() + active_accumulator->getSamplingTime()));
}
else
{
@@ -382,11 +382,11 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat )
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
if (active_accumulator && active_accumulator->hasValue())
{
- F32 t = 0.0f;
+ F64 t = 0.0;
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
if (div > 0)
{
- t = active_accumulator->getSampleCount() / div;
+ t = (F64)active_accumulator->getSampleCount() / (F64)div;
}
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
}
@@ -405,7 +405,7 @@ F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
if (active_accumulator && active_accumulator->hasValue())
{
F64 sum_of_squares = EventAccumulator::mergeSumsOfSquares(accumulator, *active_accumulator);
- return sqrtf(sum_of_squares / (accumulator.getSampleCount() + active_accumulator->getSampleCount()));
+ return sqrt(sum_of_squares / (F64)(accumulator.getSampleCount() + active_accumulator->getSampleCount()));
}
else
{
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 985f06cd59..ad4c91d85b 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -35,6 +35,11 @@
#include "llpointer.h"
#include <limits>
+#ifdef LL_WINDOWS
+#pragma warning(push)
+#pragma warning(disable : 4244) // possible loss of data on conversions
+#endif
+
class LLStopWatchControlsMixinCommon
{
public:
@@ -714,4 +719,8 @@ namespace LLTrace
};
}
+#ifdef LL_WINDOWS
+#pragma warning(pop)
+#endif
+
#endif // LL_LLTRACERECORDING_H
diff --git a/indra/llcommon/llunittype.h b/indra/llcommon/llunittype.h
index 83ce0d05a8..bb1408609a 100644
--- a/indra/llcommon/llunittype.h
+++ b/indra/llcommon/llunittype.h
@@ -31,6 +31,11 @@
#include "llpreprocessor.h"
#include "llerror.h"
+#ifdef LL_WINDOWS
+#pragma warning(push)
+#pragma warning(disable : 4244) // possible loss of data on conversions
+#endif
+
//lightweight replacement of type traits for simple type equality check
template<typename S, typename T>
struct LLIsSameType
@@ -846,4 +851,8 @@ LL_FORCE_INLINE S2 ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, un
typedef LLUnit<U64, ns::unit_name> U64##unit_name; \
typedef LLUnitImplicit<U64, ns::unit_name> U64##unit_name##Implicit
+#ifdef LL_WINDOWS
+#pragma warning(pop)
+#endif
+
#endif //LL_UNITTYPE_H
diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp
index a01d7fe415..d7b80e2545 100644
--- a/indra/llcommon/tests/lleventfilter_test.cpp
+++ b/indra/llcommon/tests/lleventfilter_test.cpp
@@ -81,13 +81,13 @@ class TestEventThrottle: public LLEventThrottleBase
public:
TestEventThrottle(F32 interval):
LLEventThrottleBase(interval),
- mAlarmRemaining(-1),
- mTimerRemaining(-1)
+ mAlarmRemaining(-1.f),
+ mTimerRemaining(-1.f)
{}
TestEventThrottle(LLEventPump& source, F32 interval):
LLEventThrottleBase(source, interval),
- mAlarmRemaining(-1),
- mTimerRemaining(-1)
+ mAlarmRemaining(-1.f),
+ mTimerRemaining(-1.f)
{}
/*----- implementation of LLEventThrottleBase timing functionality -----*/
@@ -100,12 +100,12 @@ public:
virtual bool alarmRunning() const /*override*/
{
// decrementing to exactly 0 should mean the alarm fires
- return mAlarmRemaining > 0;
+ return mAlarmRemaining > 0.f;
}
virtual void alarmCancel() /*override*/
{
- mAlarmRemaining = -1;
+ mAlarmRemaining = -1.f;
}
virtual void timerSet(F32 interval) /*override*/
@@ -116,7 +116,7 @@ public:
virtual F32 timerGetRemaining() const /*override*/
{
// LLTimer.getRemainingTimeF32() never returns negative; 0.0 means expired
- return (mTimerRemaining > 0.0)? mTimerRemaining : 0.0;
+ return (mTimerRemaining > 0.0f)? mTimerRemaining : 0.0f;
}
/*------------------- methods for manipulating time --------------------*/
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index fb2af1d2db..fae9f7023f 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -1809,7 +1809,7 @@ namespace tut
std::string q("\"");
std::string qPYTHON(q + PYTHON + q);
std::string qscript(q + scriptfile.getName() + q);
- int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(),
+ int rc = (int)_spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(),
std::forward<ARGS>(args)..., NULL);
if (rc == -1)
{
diff --git a/indra/llcommon/tests/lltrace_test.cpp b/indra/llcommon/tests/lltrace_test.cpp
index 8851f87b91..923a67ac8e 100644
--- a/indra/llcommon/tests/lltrace_test.cpp
+++ b/indra/llcommon/tests/lltrace_test.cpp
@@ -32,6 +32,10 @@
#include "lltracerecording.h"
#include "../test/lltut.h"
+#ifdef LL_WINDOWS
+#pragma warning(disable : 4244) // possible loss of data on conversions
+#endif
+
namespace LLUnits
{
// using powers of 2 to allow strict floating point equality
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index 49f2d3085a..98a58eb47e 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -262,7 +262,7 @@ namespace tut
F32 float_val = quatloos_implicit;
ensure("implicit units convert implicitly to regular values", float_val == 16);
- S32 int_val = quatloos_implicit;
+ S32 int_val = (S32)quatloos_implicit;
ensure("implicit units convert implicitly to regular values", int_val == 16);
// conversion of implicits