Age | Commit message (Collapse) | Author |
|
Drake points out that the OS X 64-bit-capable memory-query APIs recommended in
comments by some long-ago maintainer are by now themselves obsolete. He
offered this patch to update us to current macOS memory APIs.
|
|
|
|
|
|
LLInstanceTracker<T> performs validation in ~LLInstanceTracker(). Normally
validation failure logs an error and terminates the program, which is fine. In
the test executable, though, we want validation failure to throw an exception
instead so we can catch it and continue testing other failure conditions. But
since destructors in C++11 are implicitly noexcept(true), that exception never
made it out of ~LLInstanceTracker(): it crashed the test program instead.
Declaring ~LLInstanceTracker() noexcept(false) solves that, allowing the test
program to catch the exception and continue.
However, if we unconditionally declare that, then every destructor anywhere in
the inheritance hierarchy for any LLInstanceTracker subclass must also be
noexcept(false)! That's way too pervasive, especially for functionality we
only need (or want) in a specific test executable.
Instead, make the CMake macros LL_ADD_PROJECT_UNIT_TESTS() and
LL_ADD_INTEGRATION_TEST() -- with which we define all viewer build-time tests
-- define two new command-line macros: LL_TEST=testname and LL_TEST_testname.
That way, preprocessor logic in a header file can detect whether it's being
compiled for production code or for a test executable.
(While at it, encapsulate in a new GET_OPT_SOURCE_FILE_PROPERTY() CMake macro
an ugly repetitive pattern. The builtin GET_SOURCE_FILE_PROPERTY() sets the
target variable to "NOTFOUND" -- rather than an empty string -- if the
specified property wasn't set. Every call to GET_SOURCE_FILE_PROPERTY() in
LL_ADD_PROJECT_UNIT_TESTS() was followed by a test for NOTFOUND and an
assignment to "". Wrap all that in a macro whose 'unset' value is "".)
Now llinstancetracker.h can detect when we're building the LLInstanceTracker
unit test executable, and *only then* declare ~LLInstanceTracker() as
noexcept(false). We #define LLINSTANCETRACKER_DTOR_NOEXCEPT to expand either
empty or noexcept(false), also detecting clang in C++11 mode. (It all works
fine without noexcept(false) until we turn on C++11 mode.)
We also use that macro for the StatBase class in lltrace.h. Turns out some of
the infrastructure headers required for tests in general, including the
LLInstanceTracker test, use LLInstanceTracker. Fortunately that appears to be
the only other class we must annotate this way for the LLInstanceTracker tests.
|
|
The LLMemory method getCurrentRSS() is defined to return the "resident set
size," but in fact on Windows it returns the WorkingSetSize -- and that's
actually what callers want from it: the total memory consumed by the
application for statistics purposes. It's not really clear what users gain by
knowing how much of that is resident in real memory, versus the total
consumption. So despite the commentation and the method name itself, on Mac
make it return the virtual size consumed.
|
|
|
|
|
|
|
|
to suppress fatal warnings in Visual Studio.
|
|
|
|
Evidently the Mac implementation of LLMemory::getCurrentRSS() goes back to
OS X 10.3, because there was a helpful comment of the form:
------
The API used here is not capable of dealing with 64-bit memory sizes, but is
available before 10.4.
Once we start requiring 10.4, we can use the updated API, which looks like
this:
[new current implementation]
Of course, this doesn't gain us anything unless we start building the viewer
as a 64-bit executable, since that's the only way for our memory allocation to
exceed 2^32.
------
Hey, guess what, we're building 64-bit viewers now!
Thank you, whoever thoughtfully noted that, both for calling out the issue and
sparing us the research. (The comment goes back to Subversion days, so hg
blame shows only the merge-to-release changeset.)
|
|
There were two distinct LLMemory methods getCurrentRSS() and
getWorkingSetSize(). It was pointless to have both: on Windows they were
completely redundant; on other platforms getWorkingSetSize() always returned
0. (Amusingly, though the Windows implementations both made exactly the same
GetProcessMemoryInfo() call and used exactly the same logic, the code was
different in the two -- as though the second was implemented without awareness
of the first, even though they were adjacent in the source file.)
One of the actual MAINT-6996 problems was due to the fact that
getWorkingSetSize() returned U32, where getCurrentRSS() returns U64. In other
words, getWorkingSetSize() was both useless *and* wrong. Remove it, and change
its one call to getCurrentRSS() instead.
The other culprit was that in several places, the 64-bit WorkingSetSize
returned by the Windows GetProcessMemoryInfo() call (and by getCurrentRSS())
was explicitly cast to a 32-bit data type. That works only when explicitly or
implicitly (using LLUnits type conversion) scaling the value to kilobytes or
megabytes. When the size in bytes is desired, use 64-bit types instead.
In addition to the symptoms, LLMemory was overdue for a bit of cleanup.
There was a 16K block of memory called reserveMem, the comment on which read:
"reserve 16K for out of memory error handling." Yet *nothing* was ever done
with that block! If it were going to be useful, one would think someone would
at some point explicitly free the block. In fact there was a method
freeReserve(), apparently for just that purpose -- which was never called. As
things stood, reserveMem served only to *prevent* the viewer from ever using
that chunk of memory. Remove reserveMem and the unused freeReserve().
The only function of initClass() and cleanupClass() was to allocate and free
reserveMem. Remove initClass(), cleanupClass() and the LLCommon calls to them.
In a similar vein, there was an LLMemoryInfo::getPhysicalMemoryClamped()
method that returned U32Bytes. Its job was simply to return a size in bytes
that could fit into a U32 data type, returning U32_MAX if the 64-bit value
exceeded 4GB. Eliminate that; change all its calls to getPhysicalMemoryKB()
(which getPhysicalMemoryClamped() used internally anyway). We no longer care
about any platform that cannot handle 64-bit data types.
|
|
of LLSafeHandle's referenced type. Using LLSingleton gives us a well-defined
time at which the "null instance" is deleted: LLSingletonBase::deleteAll().
|
|
|
|
The recent LLSingleton work added a hook that would run during the C++
runtime's final destruction of static objects. When the LAST LLSingleton in
any module was destroyed, its destructor would call
LLSingletonBase::deleteAll(). That mechanism was intended to permit an
application consuming LLSingletons to skip making an explicit deleteAll()
call, knowing that all instantiated LLSingleton instances would eventually be
cleaned up anyway.
However -- experience proves that kicking off deleteAll() processing during
the C++ runtime's final cleanup is too late. Too much has already been
destroyed. That call tends to cause more shutdown crashes than it resolves.
This commit deletes that whole mechanism. Going forward, if you want to clean
up LLSingleton instances, you must explicitly call
LLSingletonBase::deleteAll() during the application lifetime. If you don't,
LLSingleton instances will simply be leaked -- which might be okay,
considering the application is terminating anyway.
|
|
here: https://bitbucket.org/rider_linden/doduo-viewer/commits/4f39500cb46e879dbb732e6547cc66f3ba39959e?at=default
|
|
|
|
Id rather than sha1 hash, since that is rarely used in modern
certs. The previous form was storing trusted certs using an empty sha1
hash value as the key, which meant most certificates matched... not good.
Modify the LLCertException to pass certificate information back as
LLSD rather than an LLPointer<LLCertificate>, because when the
exception is being thown from the certificate constructor that results
in one of a couple of other exceptions (even refcounting won't save
you when the problem is that the thing you're pointing to never
finished coming into being properly).
Update the certificates in the llsechandler_basic_test to modern
conventions, and extend the classes to allow for an optional
validation date so that the test can use a fixed date. Also make all
the certificates include the plain text form for ease of reference.
|
|
chat history
|
|
|
|
|
|
shouldn't be removed
|
|
The previous LLSafeHandle<T> implementation declares a static data member of
the template class but provides no (generic) definition, relying on particular
specializations to provide the definition. The data member is a function
pointer, which is called in one of the methods to produce a pointer to a
"null" T instance: that is, a dummy instance to be dereferenced in case the
wrapped T* is null.
Xcode 8.3's version of clang is bothered by the call, in a generic method,
through this (usually) uninitialized pointer. It happens that the only
specializations of LLSafeHandle do both provide definitions. I don't know
whether that's formally valid C++03 or not; but I agree with the compiler: I
don't like it.
Instead of declaring a public static function pointer which each
specialization is required to define, add a protected static method to the
template class. This protected static method simply returns a pointer to a
function-static T instance. This is functionally similar to a static
LLPointer<T> set on demand (as in the two specializations), including lazy
instantiation.
Unlike the previous implementation, this approach prohibits a given
specialization from customizing the "null" instance function. Although there
exist reasonable ways to support that (e.g. a related traits template), I
decided not to complicate the LLSafeHandle implementation to make it more
generally useful. I don't really approve of LLSafeHandle, and don't want to
see it proliferate. It's not clear that unconditionally dereferencing
LLSafeHandle<T> is in any way better than conditionally dereferencing
LLPointer<T>. It doesn't even skip the runtime conditional test; it simply
obscures it. (There exist hints in the code that at one time it might have
immediately replaced any wrapped null pointer value with the pointer to the
"null" instance, obviating the test at dereference time, but this is not the
current functionality. Perhaps it was only ever wishful thinking.)
Remove the corresponding functions and static LLPointers from the two classes
that use LLSafeHandle.
|
|
When a 'family' code isn't recognized, for instance, report the family code.
That should at least clue us in to look up and add an entry for the relevant
family code.
|
|
plus LLEventBatch::getSize(), setSize()
plus LLEventThrottle::getPostCount() and getDelay().
The interesting thing about LLEventThrottle::setInterval() and
LLEventBatch::setSize() is that either might cause an immediate flush().
|
|
These classes are as yet untested: they are straw people for API review, based
on email conversations with Caladbolg and Rider.
|
|
possible timing issues while connecting to region
|
|
LLEventPump's destructor was using LLEventPumps::instance() to unregister the
LLEventPump instance from LLEventPumps. Evidently, though, there are lingering
LLEventPump instances that persist even after the LLSingletonBase::deleteAll()
call destroys the LLEventPumps LLSingleton instance. These were resurrecting
LLEventPumps -- pointlessly, since a newly-resurrected LLEventPumps instance
can have no knowledge of the LLEventPump instance! Unregistering is
unnecessary!
What we want is a reference we can bind into each LLEventPump instance that
allows us to safely test whether the LLEventPumps instance still exists.
LLHandle is exactly that. Make LLEventPumps an LLHandleProvider and bind its
LLHandle in each LLEventPump's constructor; then the destructor can unregister
only when LLEventPumps still exists.
|
|
Apparently we've been getting away so far without this essential #include only
by "leakage" from other #includes in existing consumers. <eyeroll/>
|
|
The logging subsystem depends on two different LLSingletons for some reason.
It turns out to be very difficult to completely avoid executing any logging
calls after the LLSingletonBase::deleteAll(), but we really don't want to
resurrect those LLSingletons so late in the run for a couple stragglers.
Introduce LLSingleton::wasDeleted() query method, and use it in logging
subsystem to simply bypass last-millisecond logging requests.
|
|
|
|
|
|
|
|
currently work for textures)
|
|
|
|
These are mostly things that were in fact erroneous, but accepted by older
compilers.
This changeset has not yet been built with Visual Studio 2013 or Linux gcc,
even with -std=c++11.
This changeset has not been built *without* -std=c++11. It should be used in
conjunction with a corresponding change to LL_BUILD_DARWIN_BASE_SWITCHES in
viewer-build-variables/variables.
This is a work in progress. We do not assert that this changeset completes the
work needed to turn on -std=c++11, even on the Mac.
|
|
type. Temporary construction until UDP path goes away.
|
|
|
|
|
|
|
|
clang has started to reject our non-const comparison operator methods used
within standard algorithms.
|
|
|
|
|
|
DRTVWR-412 Bento (avatar skeleton extensions)
|
|
The present CMake logic wants to pass FIXED:NO to the linker for 64-bit
builds, which on the face of it seems like a Good Thing: it permits code to be
relocated in memory, preventing collisions if two libraries happen to want to
load into overlapping address ranges.
However the way it's being specified is wrong and harmful. Passing /FIXED:NO
to the compiler command line engages /FI (Forced Include!) of a nonexistent
file XED:NO -- producing lots of baffling fatal compile errors.
Thanks Callum for diagnosing this!
|
|
|
|
|
|
|
|
Some day llmake() will be unnecessary because compiler deduction of class
template arguments from constructor arguments has been approved by ISO.
|
|
LLPrivateMemoryPool and LLPrivateMemoryPoolManager have assumed that it's
always valid to cast a pointer to U32. With 64-bit pointers, no longer true.
|