summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorKitty Barnett <develop@catznip.com>2023-02-08 14:56:38 +0100
committerKitty Barnett <develop@catznip.com>2023-02-08 14:56:38 +0100
commit7b563470fbade848d7eeb52d5088f3ca9b9c6905 (patch)
treedc3faed194d6ce8cc8d5b18175dfad17a1490cd8 /indra/llcommon
parentf3cd329b585ef55a66f2a824f010d1a54d67d8d2 (diff)
parent8d21d29bd7fa038db632ff90fb0e1207d0713ca2 (diff)
Merge branch 'main' into xcode-14.1
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rw-r--r--indra/llcommon/llapr.cpp4
-rw-r--r--indra/llcommon/llcoros.cpp74
-rw-r--r--indra/llcommon/llcoros.h6
-rw-r--r--indra/llcommon/llerror.cpp2
-rw-r--r--indra/llcommon/llsdserialize.cpp121
-rw-r--r--indra/llcommon/llsdserialize.h6
-rw-r--r--indra/llcommon/llthreadlocalstorage.cpp115
-rw-r--r--indra/llcommon/llthreadlocalstorage.h98
-rw-r--r--indra/llcommon/lltrace.cpp2
-rw-r--r--indra/llcommon/lltraceaccumulators.cpp2
-rw-r--r--indra/llcommon/lltracerecording.cpp14
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp6
-rw-r--r--indra/llcommon/lltracethreadrecorder.h3
-rw-r--r--indra/llcommon/lluuid.cpp30
-rw-r--r--indra/llcommon/lluuid.h8
-rw-r--r--indra/llcommon/threadsafeschedule.h2
17 files changed, 120 insertions, 374 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index df65828d02..108149b5f7 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -108,7 +108,6 @@ set(llcommon_SOURCE_FILES
llsys.cpp
lltempredirect.cpp
llthread.cpp
- llthreadlocalstorage.cpp
llthreadsafequeue.cpp
lltimer.cpp
lltrace.cpp
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index db94765871..435531f86f 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -30,7 +30,6 @@
#include "llapr.h"
#include "llmutex.h"
#include "apr_dso.h"
-#include "llthreadlocalstorage.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@@ -54,7 +53,6 @@ void ll_init_apr()
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
}
- LLThreadLocalPointerBase::initAllThreadLocalStorage();
gAPRInitialized = true;
}
@@ -70,8 +68,6 @@ void ll_cleanup_apr()
LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL;
- LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
-
if (gAPRPoolp)
{
apr_pool_destroy(gAPRPoolp);
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 14bfb98629..70d8dfc8b9 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -288,25 +288,15 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
return name;
}
+namespace
+{
+
#if LL_WINDOWS
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name)
+U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
{
- // C++ exceptions were logged in toplevelTryWrapper, but not SEH
- // log SEH exceptions here, to make sure it gets into bugsplat's
- // report and because __try won't allow std::string operations
- if (code != STATUS_MSC_EXCEPTION)
- {
- LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
- }
- // Handle bugsplat here, since GetExceptionInformation() can only be
- // called from within filter for __except(filter), not from __except's {}
- // Bugsplat should get all exceptions, C++ and SEH
- LLApp::instance()->reportCrashToBugsplat(exception_infop);
-
- // Only convert non C++ exceptions.
if (code == STATUS_MSC_EXCEPTION)
{
// C++ exception, go on
@@ -319,28 +309,38 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
}
}
-void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
+void sehandle(const LLCoros::callable_t& callable)
{
__try
{
- LLCoros::toplevelTryWrapper(name, callable);
+ callable();
}
- __except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
+ __except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
{
- // convert to C++ styled exception for handlers other than bugsplat
+ // convert to C++ styled exception
// Note: it might be better to use _se_set_translator
// if you want exception to inherit full callstack
- //
- // in case of bugsplat this will get to exceptionTerminateHandler and
- // looks like fiber will terminate application after that
char integer_string[512];
- sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());
+ sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
throw std::exception(integer_string);
}
}
-#endif
-void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
+#else // ! LL_WINDOWS
+
+inline void sehandle(const LLCoros::callable_t& callable)
+{
+ callable();
+}
+
+#endif // ! LL_WINDOWS
+
+} // anonymous namespace
+
+// Top-level wrapper around caller's coroutine callable.
+// Normally we like to pass strings and such by const reference -- but in this
+// case, we WANT to copy both the name and the callable to our local stack!
+void LLCoros::toplevel(std::string name, callable_t callable)
{
// keep the CoroData on this top-level function's stack frame
CoroData corodata(name);
@@ -350,12 +350,12 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
// run the code the caller actually wants in the coroutine
try
{
- callable();
+ sehandle(callable);
}
catch (const Stop& exc)
{
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
- << exc.what() << LL_ENDL;
+ << exc.what() << LL_ENDL;
}
catch (const LLContinueError&)
{
@@ -366,36 +366,14 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
}
catch (...)
{
-#if LL_WINDOWS
- // Any OTHER kind of uncaught exception will cause the viewer to
- // crash, SEH handling should catch it and report to bugsplat.
- LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
- // to not modify callstack
- throw;
-#else
// Stash any OTHER kind of uncaught exception in the rethrow() queue
// to be rethrown by the main fiber.
LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
<< name << LL_ENDL;
LLCoros::instance().saveException(name, std::current_exception());
-#endif
}
}
-// Top-level wrapper around caller's coroutine callable.
-// Normally we like to pass strings and such by const reference -- but in this
-// case, we WANT to copy both the name and the callable to our local stack!
-void LLCoros::toplevel(std::string name, callable_t callable)
-{
-#if LL_WINDOWS
- // Because SEH can's have unwinding, need to call a wrapper
- // 'try' is inside SEH handling to not catch LLContinue
- sehHandle(name, callable);
-#else
- toplevelTryWrapper(name, callable);
-#endif
-}
-
//static
void LLCoros::checkStop()
{
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index dbff921f16..966ce03296 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -307,11 +307,7 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
- void toplevelTryWrapper(const std::string& name, const callable_t& callable);
-#if LL_WINDOWS
- void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
-#endif
- void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
+ void toplevel(std::string name, callable_t callable);
struct CoroData;
static CoroData& get_CoroData(const std::string& caller);
void saveException(const std::string& name, std::exception_ptr exc);
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 519426e9d1..f9eda3cd4e 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -943,7 +943,7 @@ namespace LLError
for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
{
const LLSD& entry = *a;
- if (entry.isMap() && !entry.emptyMap())
+ if (entry.isMap() && entry.size() != 0)
{
ELevel level = decodeLevel(entry["level"]);
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index af57f4ac5e..73206f3d40 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -34,6 +34,9 @@
#include <iostream>
#include "apr_base64.h"
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/stream.hpp>
+
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
#else
@@ -2128,7 +2131,9 @@ std::string zip_llsd(LLSD& data)
{ //copy result into output
if (strm.avail_out >= CHUNK)
{
- free(output);
+ deflateEnd(&strm);
+ if(output)
+ free(output);
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
return std::string();
}
@@ -2151,7 +2156,9 @@ std::string zip_llsd(LLSD& data)
}
else
{
- free(output);
+ deflateEnd(&strm);
+ if(output)
+ free(output);
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
return std::string();
}
@@ -2162,7 +2169,8 @@ std::string zip_llsd(LLSD& data)
std::string result((char*) output, size);
deflateEnd(&strm);
- free(output);
+ if(output)
+ free(output);
return result;
}
@@ -2172,53 +2180,66 @@ std::string zip_llsd(LLSD& data)
// and deserializes from that copy using LLSDSerialize
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size)
{
+ std::unique_ptr<U8[]> in = std::unique_ptr<U8[]>(new(std::nothrow) U8[size]);
+ if (!in)
+ {
+ return ZR_MEM_ERROR;
+ }
+ is.read((char*) in.get(), size);
+
+ return unzip_llsd(data, in.get(), size);
+}
+
+LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32 size)
+{
U8* result = NULL;
llssize cur_size = 0;
z_stream strm;
- const U32 CHUNK = 65536;
+ constexpr U32 CHUNK = 1024 * 512;
- U8 *in = new(std::nothrow) U8[size];
- if (!in)
+ static thread_local std::unique_ptr<U8[]> out;
+ if (!out)
{
- return ZR_MEM_ERROR;
+ out = std::unique_ptr<U8[]>(new(std::nothrow) U8[CHUNK]);
}
- is.read((char*) in, size);
-
- U8 out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = size;
- strm.next_in = in;
+ strm.next_in = const_cast<U8*>(in);
S32 ret = inflateInit(&strm);
do
{
strm.avail_out = CHUNK;
- strm.next_out = out;
+ strm.next_out = out.get();
ret = inflate(&strm, Z_NO_FLUSH);
- if (ret == Z_STREAM_ERROR)
+ switch (ret)
+ {
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
{
inflateEnd(&strm);
free(result);
- delete [] in;
return ZR_DATA_ERROR;
}
-
- switch (ret)
+ case Z_STREAM_ERROR:
+ case Z_BUF_ERROR:
{
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR;
- case Z_DATA_ERROR:
+ inflateEnd(&strm);
+ free(result);
+ return ZR_BUFFER_ERROR;
+ }
+
case Z_MEM_ERROR:
+ {
inflateEnd(&strm);
free(result);
- delete [] in;
return ZR_MEM_ERROR;
- break;
+ }
}
U32 have = CHUNK-strm.avail_out;
@@ -2231,17 +2252,15 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
{
free(result);
}
- delete[] in;
return ZR_MEM_ERROR;
}
result = new_result;
- memcpy(result+cur_size, out, have);
+ memcpy(result+cur_size, out.get(), have);
cur_size += have;
- } while (ret == Z_OK);
+ } while (ret == Z_OK && ret != Z_STREAM_END);
inflateEnd(&strm);
- delete [] in;
if (ret != Z_STREAM_END)
{
@@ -2251,37 +2270,11 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
//result now points to the decompressed LLSD block
{
- std::istringstream istr;
- // Since we are using this for meshes, data we are dealing with tend to be large.
- // So string can potentially fail to allocate, make sure this won't cause problems
- try
- {
- std::string res_str((char*)result, cur_size);
-
- std::string deprecated_header("<? LLSD/Binary ?>");
-
- if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
- {
- res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
- }
- cur_size = res_str.size();
-
- istr.str(res_str);
- }
-#ifdef LL_WINDOWS
- catch (std::length_error)
- {
- free(result);
- return ZR_SIZE_ERROR;
- }
-#endif
- catch (std::bad_alloc&)
- {
- free(result);
- return ZR_MEM_ERROR;
- }
+ char* result_ptr = strip_deprecated_header((char*)result, cur_size);
- if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))
+ boost::iostreams::stream<boost::iostreams::array_source> istrm(result_ptr, cur_size);
+
+ if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH))
{
free(result);
return ZR_PARSE_ERROR;
@@ -2395,4 +2388,22 @@ U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size
return result;
}
+char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size)
+{
+ const char* deprecated_header = "<? LLSD/Binary ?>";
+ constexpr size_t deprecated_header_size = 17;
+
+ if (cur_size > deprecated_header_size
+ && memcmp(in, deprecated_header, deprecated_header_size) == 0)
+ {
+ in = in + deprecated_header_size;
+ cur_size = cur_size - deprecated_header_size;
+ if (header_size)
+ {
+ *header_size = deprecated_header_size + 1;
+ }
+ }
+
+ return in;
+}
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index bd5ef668c0..2f12c6d1ff 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -858,9 +858,12 @@ public:
ZR_SIZE_ERROR,
ZR_DATA_ERROR,
ZR_PARSE_ERROR,
+ ZR_BUFFER_ERROR,
+ ZR_VERSION_ERROR
} EZipRresult;
// return OK or reason for failure
static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size);
+ static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size);
};
//dirty little zip functions -- yell at davep
@@ -868,4 +871,7 @@ LL_COMMON_API std::string zip_llsd(LLSD& data);
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, size_t& outsize,std::istream& is, S32 size);
+
+// returns a pointer to the array or past the array if the deprecated header exists
+LL_COMMON_API char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size = nullptr);
#endif // LL_LLSDSERIALIZE_H
diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp
deleted file mode 100644
index d8a063e8d5..0000000000
--- a/indra/llcommon/llthreadlocalstorage.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * @file llthreadlocalstorage.cpp
- * @author Richard
- * @date 2013-1-11
- * @brief implementation of thread local storage utility classes
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "llthreadlocalstorage.h"
-#include "llapr.h"
-
-//
-//LLThreadLocalPointerBase
-//
-bool LLThreadLocalPointerBase::sInitialized = false;
-
-void LLThreadLocalPointerBase::set( void* value )
-{
- llassert(sInitialized && mThreadKey);
-
- apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey);
- if (result != APR_SUCCESS)
- {
- ll_apr_warn_status(result);
- LL_ERRS() << "Failed to set thread local data" << LL_ENDL;
- }
-}
-
-void* LLThreadLocalPointerBase::get() const
-{
- // llassert(sInitialized);
- void* ptr;
- apr_status_t result =
- apr_threadkey_private_get(&ptr, mThreadKey);
- if (result != APR_SUCCESS)
- {
- ll_apr_warn_status(result);
- LL_ERRS() << "Failed to get thread local data" << LL_ENDL;
- }
- return ptr;
-}
-
-
-void LLThreadLocalPointerBase::initStorage( )
-{
- apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp);
- if (result != APR_SUCCESS)
- {
- ll_apr_warn_status(result);
- LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL;
- }
-}
-
-void LLThreadLocalPointerBase::destroyStorage()
-{
- if (sInitialized)
- {
- if (mThreadKey)
- {
- apr_status_t result = apr_threadkey_private_delete(mThreadKey);
- if (result != APR_SUCCESS)
- {
- ll_apr_warn_status(result);
- LL_ERRS() << "Failed to delete thread local data" << LL_ENDL;
- }
- }
- }
-}
-
-//static
-void LLThreadLocalPointerBase::initAllThreadLocalStorage()
-{
- if (!sInitialized)
- {
- for (auto& base : instance_snapshot())
- {
- base.initStorage();
- }
- sInitialized = true;
- }
-}
-
-//static
-void LLThreadLocalPointerBase::destroyAllThreadLocalStorage()
-{
- if (sInitialized)
- {
- //for (auto& base : instance_snapshot())
- //{
- // base.destroyStorage();
- //}
- sInitialized = false;
- }
-}
diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h
index 3b5786023f..bdd28ec865 100644
--- a/indra/llcommon/llthreadlocalstorage.h
+++ b/indra/llcommon/llthreadlocalstorage.h
@@ -30,100 +30,6 @@
#include "llinstancetracker.h"
-class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
-{
-public:
- LLThreadLocalPointerBase()
- : mThreadKey(NULL)
- {
- if (sInitialized)
- {
- initStorage();
- }
- }
-
- LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
- : mThreadKey(NULL)
- {
- if (sInitialized)
- {
- initStorage();
- }
- }
-
- ~LLThreadLocalPointerBase()
- {
- destroyStorage();
- }
-
- static void initAllThreadLocalStorage();
- static void destroyAllThreadLocalStorage();
-
-protected:
- void set(void* value);
-
- void* get() const;
-
- void initStorage();
- void destroyStorage();
-
-protected:
- struct apr_threadkey_t* mThreadKey;
- static bool sInitialized;
-};
-
-template <typename T>
-class LLThreadLocalPointer : public LLThreadLocalPointerBase
-{
-public:
-
- LLThreadLocalPointer()
- {}
-
- explicit LLThreadLocalPointer(T* value)
- {
- set(value);
- }
-
-
- LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
- : LLThreadLocalPointerBase(other)
- {
- set(other.get());
- }
-
- LL_FORCE_INLINE T* get() const
- {
- return (T*)LLThreadLocalPointerBase::get();
- }
-
- T* operator -> () const
- {
- return (T*)get();
- }
-
- T& operator*() const
- {
- return *(T*)get();
- }
-
- LLThreadLocalPointer<T>& operator = (T* value)
- {
- set((void*)value);
- return *this;
- }
-
- bool operator ==(const T* other) const
- {
- if (!sInitialized) return false;
- return get() == other;
- }
-
- bool isNull() const { return !sInitialized || get() == NULL; }
-
- bool notNull() const { return sInitialized && get() != NULL; }
-};
-
template<typename DERIVED_TYPE>
class LLThreadLocalSingletonPointer
{
@@ -139,10 +45,10 @@ public:
}
private:
- static LL_THREAD_LOCAL DERIVED_TYPE* sInstance;
+ static thread_local DERIVED_TYPE* sInstance;
};
template<typename DERIVED_TYPE>
-LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
+thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
#endif // LL_LLTHREADLOCALSTORAGE_H
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index 7ad50d1288..ff671a8370 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description )
mDescription(description ? description : "")
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
- if (LLTrace::get_thread_recorder().notNull())
+ if (LLTrace::get_thread_recorder() != NULL)
{
LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL;
}
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index 7c38cdb7cd..6bd886ae98 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent()
mStackTimers.makeCurrent();
mMemStats.makeCurrent();
- ThreadRecorder* thread_recorder = get_thread_recorder().get();
+ ThreadRecorder* thread_recorder = get_thread_recorder();
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
// update stacktimer parent pointers
for (size_t i = 0, end_i = mStackTimers.size(); i < end_i; i++)
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 8414b234e0..dd148dd08a 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -95,7 +95,7 @@ Recording::~Recording()
// allow recording destruction without thread recorder running,
// otherwise thread shutdown could crash if a recording outlives the thread recorder
// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
- if (isStarted() && LLTrace::get_thread_recorder().notNull())
+ if (isStarted() && LLTrace::get_thread_recorder() != NULL)
{
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
}
@@ -112,9 +112,9 @@ void Recording::update()
// must have
llassert(mActiveBuffers != NULL
- && LLTrace::get_thread_recorder().notNull());
+ && LLTrace::get_thread_recorder() != NULL);
- if(!mActiveBuffers->isCurrent())
+ if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
{
AccumulatorBufferGroup* buffers = mBuffers.write();
LLTrace::get_thread_recorder()->deactivate(buffers);
@@ -144,7 +144,7 @@ void Recording::handleStart()
mSamplingTimer.reset();
mBuffers.setStayUnique(true);
// must have thread recorder running on this thread
- llassert(LLTrace::get_thread_recorder().notNull());
+ llassert(LLTrace::get_thread_recorder() != NULL);
mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write());
#endif
}
@@ -155,7 +155,7 @@ void Recording::handleStop()
#if LL_TRACE_ENABLED
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
// must have thread recorder running on this thread
- llassert(LLTrace::get_thread_recorder().notNull());
+ llassert(LLTrace::get_thread_recorder() != NULL);
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
mActiveBuffers = NULL;
mBuffers.setStayUnique(false);
@@ -1182,8 +1182,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth
PeriodicRecording& get_frame_recording()
{
- static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
- return *sRecording;
+ static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
+ return sRecording;
}
}
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index d10312e0ec..4028a5ce97 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder()
return sMasterThreadRecorder;
}
-LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
+ThreadRecorder*& get_thread_recorder_ptr()
{
- static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
+ static thread_local ThreadRecorder* s_thread_recorder;
return s_thread_recorder;
}
-const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
+ThreadRecorder* get_thread_recorder()
{
return get_thread_recorder_ptr();
}
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
index 1294d4318f..8ee6729ac6 100644
--- a/indra/llcommon/lltracethreadrecorder.h
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -32,7 +32,6 @@
#include "llmutex.h"
#include "lltraceaccumulators.h"
-#include "llthreadlocalstorage.h"
namespace LLTrace
{
@@ -92,7 +91,7 @@ namespace LLTrace
};
- const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
+ ThreadRecorder* get_thread_recorder();
void set_thread_recorder(ThreadRecorder*);
void set_master_thread_recorder(ThreadRecorder*);
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index acce8366ea..6f9e09a587 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -1009,36 +1009,6 @@ LLUUID::LLUUID()
return !(word[0] | word[1] | word[2] | word[3]);
}
-// Copy constructor
- LLUUID::LLUUID(const LLUUID& rhs)
-{
- U32 *tmp = (U32 *)mData;
- U32 *rhstmp = (U32 *)rhs.mData;
- tmp[0] = rhstmp[0];
- tmp[1] = rhstmp[1];
- tmp[2] = rhstmp[2];
- tmp[3] = rhstmp[3];
-}
-
- LLUUID::~LLUUID()
-{
-}
-
-// Assignment
- LLUUID& LLUUID::operator=(const LLUUID& rhs)
-{
- // No need to check the case where this==&rhs. The branch is slower than the write.
- U32 *tmp = (U32 *)mData;
- U32 *rhstmp = (U32 *)rhs.mData;
- tmp[0] = rhstmp[0];
- tmp[1] = rhstmp[1];
- tmp[2] = rhstmp[2];
- tmp[3] = rhstmp[3];
-
- return *this;
-}
-
-
LLUUID::LLUUID(const char *in_string)
{
if (!in_string || in_string[0] == 0)
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index 86a396ab06..c139c4eb4e 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -55,10 +55,7 @@ public:
LLUUID();
explicit LLUUID(const char *in_string); // Convert from string.
explicit LLUUID(const std::string& in_string); // Convert from string.
- LLUUID(const LLUUID &in);
- LLUUID &operator=(const LLUUID &rhs);
-
- ~LLUUID();
+ ~LLUUID() = default;
//
// MANIPULATORS
@@ -131,6 +128,9 @@ public:
U8 mData[UUID_BYTES];
};
+static_assert(std::is_trivially_copyable<LLUUID>::value, "LLUUID must be trivial copy");
+static_assert(std::is_trivially_move_assignable<LLUUID>::value, "LLUUID must be trivial move");
+static_assert(std::is_standard_layout<LLUUID>::value, "LLUUID must be a standard layout type");
typedef std::vector<LLUUID> uuid_vec_t;
typedef std::set<LLUUID> uuid_set_t;
diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h
index 2d82d6a15e..92bc7da940 100644
--- a/indra/llcommon/threadsafeschedule.h
+++ b/indra/llcommon/threadsafeschedule.h
@@ -248,7 +248,7 @@ namespace LL
TimePoint until = TimePoint::clock::now() + std::chrono::hours(24);
pop_result popped = tryPopUntil_(lock, until, tt);
if (popped == POPPED)
- return std::move(tt);
+ return tt;
// DONE: throw, just as super::pop() does
if (popped == DONE)