Automated merge with ssh://bitbucket.org/lindenlab/viewer-release
commit
df55db4aa0
|
|
@ -42,6 +42,7 @@
|
|||
#include "lldiriterator.h"
|
||||
#include "v4coloru.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
// system libraries
|
||||
#include <iostream>
|
||||
|
|
@ -634,7 +635,7 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
// Cleanup and exit
|
||||
LLImage::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLImage);
|
||||
if (fast_timer_log_thread)
|
||||
{
|
||||
fast_timer_log_thread->shutdown();
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ set(llcommon_HEADER_FILES
|
|||
llmortician.h
|
||||
llnametable.h
|
||||
llpointer.h
|
||||
llpounceable.h
|
||||
llpredicate.h
|
||||
llpreprocessor.h
|
||||
llpriqueuemap.h
|
||||
|
|
@ -310,6 +311,7 @@ if (LL_TESTS)
|
|||
LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(llpounceable "" "${test_libs}")
|
||||
|
||||
# *TODO - reenable these once tcmalloc libs no longer break the build.
|
||||
#ADD_BUILD_TEST(llallocator llcommon)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "lleventtimer.h"
|
||||
#include "google_breakpad/exception_handler.h"
|
||||
#include "stringize.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
//
|
||||
// Signal handling
|
||||
|
|
@ -177,7 +178,7 @@ LLApp::~LLApp()
|
|||
|
||||
if(mExceptionHandler != 0) delete mExceptionHandler;
|
||||
|
||||
LLCommon::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLCommon);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* @file llcleanup.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2015-05-20
|
||||
* @brief Mechanism for cleaning up subsystem resources
|
||||
*
|
||||
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
|
||||
* Copyright (c) 2015, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLCLEANUP_H)
|
||||
#define LL_LLCLEANUP_H
|
||||
|
||||
#include "llerror.h"
|
||||
|
||||
// Instead of directly calling SomeClass::cleanupClass(), use
|
||||
// SUBSYSTEM_CLEANUP(SomeClass);
|
||||
// This logs the call as well as performing it. That gives us a baseline
|
||||
// subsystem shutdown order against which to compare subsequent dynamic
|
||||
// shutdown schemes.
|
||||
#define SUBSYSTEM_CLEANUP(CLASSNAME) \
|
||||
do { \
|
||||
LL_INFOS("Cleanup") << "Calling " #CLASSNAME "::cleanupClass()" << LL_ENDL; \
|
||||
CLASSNAME::cleanupClass(); \
|
||||
} while (0)
|
||||
// Use ancient do { ... } while (0) macro trick to permit a block of
|
||||
// statements with the same syntax as a single statement.
|
||||
|
||||
#endif /* ! defined(LL_LLCLEANUP_H) */
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llthread.h"
|
||||
#include "lltrace.h"
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
//static
|
||||
BOOL LLCommon::sAprInitialized = FALSE;
|
||||
|
|
@ -63,11 +64,11 @@ void LLCommon::cleanupClass()
|
|||
sMasterThreadRecorder = NULL;
|
||||
LLTrace::set_master_thread_recorder(NULL);
|
||||
LLThreadSafeRefCount::cleanupThreadSafeRefCount();
|
||||
LLTimer::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLTimer);
|
||||
if (sAprInitialized)
|
||||
{
|
||||
ll_cleanup_apr();
|
||||
sAprInitialized = FALSE;
|
||||
}
|
||||
LLMemory::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLMemory);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,217 @@
|
|||
/**
|
||||
* @file llpounceable.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2015-05-22
|
||||
* @brief LLPounceable is tangentially related to a future: it's a holder for
|
||||
* a value that may or may not exist yet. Unlike a future, though,
|
||||
* LLPounceable freely allows reading the held value. (If the held
|
||||
* type T does not have a distinguished "empty" value, consider using
|
||||
* LLPounceable<boost::optional<T>>.)
|
||||
*
|
||||
* LLPounceable::callWhenReady() is this template's claim to fame. It
|
||||
* allows its caller to "pounce" on the held value as soon as it
|
||||
* becomes non-empty. Call callWhenReady() with any C++ callable
|
||||
* accepting T. If the held value is already non-empty, callWhenReady()
|
||||
* will immediately call the callable with the held value. If the held
|
||||
* value is empty, though, callWhenReady() will enqueue the callable
|
||||
* for later. As soon as LLPounceable is assigned a non-empty held
|
||||
* value, it will flush the queue of deferred callables.
|
||||
*
|
||||
* Consider a global LLMessageSystem* gMessageSystem. Message system
|
||||
* initialization happens at a very specific point during viewer
|
||||
* initialization. Other subsystems want to register callbacks on the
|
||||
* LLMessageSystem instance as soon as it's initialized, but their own
|
||||
* initialization may precede that. If we define gMessageSystem to be
|
||||
* an LLPounceable<LLMessageSystem*>, a subsystem can use
|
||||
* callWhenReady() to either register immediately (if gMessageSystem
|
||||
* is already up and runnning) or register as soon as gMessageSystem
|
||||
* is set with a new, initialized instance.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
|
||||
* Copyright (c) 2015, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLPOUNCEABLE_H)
|
||||
#define LL_LLPOUNCEABLE_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <queue>
|
||||
|
||||
// Forward declare the user template, since we want to be able to point to it
|
||||
// in some of its implementation classes.
|
||||
template <typename T, class TAG>
|
||||
class LLPounceable;
|
||||
|
||||
template <typename T, typename TAG>
|
||||
struct LLPounceableTraits
|
||||
{
|
||||
// Call callWhenReady() with any callable accepting T.
|
||||
typedef boost::function<void (typename boost::call_traits<T>::param_type)> func_t;
|
||||
// Our actual queue is a simple queue of such callables.
|
||||
typedef std::queue<func_t> queue_t;
|
||||
// owner pointer type
|
||||
typedef LLPounceable<T, TAG>* owner_ptr;
|
||||
};
|
||||
|
||||
// Tag types distinguish the two different implementations of LLPounceable's
|
||||
// queue.
|
||||
struct LLPounceableQueue {};
|
||||
struct LLPounceableStatic {};
|
||||
|
||||
// generic LLPounceableQueueImpl deliberately omitted: only the above tags are
|
||||
// legal
|
||||
template <typename T, class TAG>
|
||||
class LLPounceableQueueImpl;
|
||||
|
||||
// The implementation selected by LLPounceableStatic uses an LLSingleton
|
||||
// because we can't count on a data member queue being initialized at the time
|
||||
// we start getting callWhenReady() calls. This is that LLSingleton.
|
||||
template <typename T>
|
||||
class LLPounceableQueueSingleton:
|
||||
public LLSingleton<LLPounceableQueueSingleton<T> >
|
||||
{
|
||||
private:
|
||||
typedef LLPounceableTraits<T, LLPounceableStatic> traits;
|
||||
typedef typename traits::owner_ptr owner_ptr;
|
||||
typedef typename traits::queue_t queue_t;
|
||||
|
||||
// For a given held type T, every LLPounceable<T, LLPounceableStatic>
|
||||
// instance will call on the SAME LLPounceableQueueSingleton instance --
|
||||
// given how class statics work. We must keep a separate queue for each
|
||||
// LLPounceable instance. Use a hash map for that.
|
||||
typedef boost::unordered_map<owner_ptr, queue_t> map_t;
|
||||
|
||||
public:
|
||||
// Disambiguate queues belonging to different LLPounceables.
|
||||
queue_t& get(owner_ptr owner)
|
||||
{
|
||||
// operator[] has find-or-create semantics -- just what we want!
|
||||
return mMap[owner];
|
||||
}
|
||||
|
||||
private:
|
||||
map_t mMap;
|
||||
};
|
||||
|
||||
// LLPounceableQueueImpl that uses the above LLSingleton
|
||||
template <typename T>
|
||||
class LLPounceableQueueImpl<T, LLPounceableStatic>
|
||||
{
|
||||
public:
|
||||
typedef LLPounceableTraits<T, LLPounceableStatic> traits;
|
||||
typedef typename traits::owner_ptr owner_ptr;
|
||||
typedef typename traits::queue_t queue_t;
|
||||
|
||||
queue_t& get(owner_ptr owner) const
|
||||
{
|
||||
// this Impl contains nothing; it delegates to the Singleton
|
||||
return LLPounceableQueueSingleton<T>::instance().get(owner);
|
||||
}
|
||||
};
|
||||
|
||||
// The implementation selected by LLPounceableQueue directly contains the
|
||||
// queue of interest, suitable for an LLPounceable we can trust to be fully
|
||||
// initialized when it starts getting callWhenReady() calls.
|
||||
template <typename T>
|
||||
class LLPounceableQueueImpl<T, LLPounceableQueue>
|
||||
{
|
||||
public:
|
||||
typedef LLPounceableTraits<T, LLPounceableQueue> traits;
|
||||
typedef typename traits::owner_ptr owner_ptr;
|
||||
typedef typename traits::queue_t queue_t;
|
||||
|
||||
queue_t& get(owner_ptr)
|
||||
{
|
||||
return mQueue;
|
||||
}
|
||||
|
||||
private:
|
||||
queue_t mQueue;
|
||||
};
|
||||
|
||||
// LLPounceable<T> is for an LLPounceable instance on the heap or the stack.
|
||||
// LLPounceable<T, LLPounceableStatic> is for a static LLPounceable instance.
|
||||
template <typename T, class TAG=LLPounceableQueue>
|
||||
class LLPounceable
|
||||
{
|
||||
private:
|
||||
typedef LLPounceableTraits<T, TAG> traits;
|
||||
typedef typename traits::owner_ptr owner_ptr;
|
||||
typedef typename traits::queue_t queue_t;
|
||||
|
||||
public:
|
||||
typedef typename traits::func_t func_t;
|
||||
|
||||
// By default, both the initial value and the distinguished empty value
|
||||
// are a default-constructed T instance. However you can explicitly
|
||||
// specify each.
|
||||
LLPounceable(typename boost::call_traits<T>::value_type init =boost::value_initialized<T>(),
|
||||
typename boost::call_traits<T>::param_type empty=boost::value_initialized<T>()):
|
||||
mHeld(init),
|
||||
mEmpty(empty)
|
||||
{}
|
||||
|
||||
// make read access to mHeld as cheap and transparent as possible
|
||||
operator T () const { return mHeld; }
|
||||
typename boost::remove_pointer<T>::type operator*() const { return *mHeld; }
|
||||
typename boost::call_traits<T>::value_type operator->() const { return mHeld; }
|
||||
// uncomment 'explicit' as soon as we allow C++11 compilation
|
||||
/*explicit*/ operator bool() const { return bool(mHeld); }
|
||||
bool operator!() const { return ! mHeld; }
|
||||
|
||||
// support both assignment (dumb ptr idiom) and reset() (smart ptr)
|
||||
void operator=(typename boost::call_traits<T>::param_type value)
|
||||
{
|
||||
reset(value);
|
||||
}
|
||||
|
||||
void reset(typename boost::call_traits<T>::param_type value)
|
||||
{
|
||||
mHeld = value;
|
||||
// If this new value is non-empty, flush anything pending in the queue.
|
||||
if (mHeld != mEmpty)
|
||||
{
|
||||
queue_t& queue(get_queue());
|
||||
while (! queue.empty())
|
||||
{
|
||||
queue.front()(mHeld);
|
||||
queue.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// our claim to fame
|
||||
void callWhenReady(const func_t& func)
|
||||
{
|
||||
if (mHeld != mEmpty)
|
||||
{
|
||||
// If the held value is already non-empty, immediately call func()
|
||||
func(mHeld);
|
||||
}
|
||||
else
|
||||
{
|
||||
// held value still empty, queue func() for later
|
||||
get_queue().push(func);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
queue_t& get_queue() { return mQueue.get(this); }
|
||||
|
||||
// Store both the current and the empty value.
|
||||
// MAYBE: Might be useful to delegate to LLPounceableTraits the meaning of
|
||||
// testing for "empty." For some types we want operator!(); for others we
|
||||
// want to compare to a distinguished value.
|
||||
typename boost::call_traits<T>::value_type mHeld, mEmpty;
|
||||
// This might either contain the queue (LLPounceableQueue) or delegate to
|
||||
// an LLSingleton (LLPounceableStatic).
|
||||
LLPounceableQueueImpl<T, TAG> mQueue;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLPOUNCEABLE_H) */
|
||||
|
|
@ -269,7 +269,7 @@ public:
|
|||
|
||||
~ScopedRegistrar()
|
||||
{
|
||||
if (!singleton_t::destroyed())
|
||||
if (singleton_t::instanceExists())
|
||||
{
|
||||
popScope();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,31 +166,19 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static DERIVED_TYPE* getIfExists()
|
||||
{
|
||||
return sData.mInstance;
|
||||
}
|
||||
|
||||
// Reference version of getInstance()
|
||||
// Preferred over getInstance() as it disallows checking for NULL
|
||||
static DERIVED_TYPE& instance()
|
||||
{
|
||||
return *getInstance();
|
||||
}
|
||||
|
||||
// Has this singleton been created uet?
|
||||
// Use this to avoid accessing singletons before the can safely be constructed
|
||||
|
||||
// Has this singleton been created yet?
|
||||
// Use this to avoid accessing singletons before they can safely be constructed.
|
||||
static bool instanceExists()
|
||||
{
|
||||
return sData.mInitState == INITIALIZED;
|
||||
}
|
||||
|
||||
// Has this singleton already been deleted?
|
||||
// Use this to avoid accessing singletons from a static object's destructor
|
||||
static bool destroyed()
|
||||
{
|
||||
return sData.mInitState == DELETED;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
/**
|
||||
* @file llpounceable_test.cpp
|
||||
* @author Nat Goodspeed
|
||||
* @date 2015-05-22
|
||||
* @brief Test for llpounceable.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
|
||||
* Copyright (c) 2015, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Precompiled header
|
||||
#include "linden_common.h"
|
||||
// associated header
|
||||
#include "llpounceable.h"
|
||||
// STL headers
|
||||
// std headers
|
||||
// external library headers
|
||||
#include <boost/bind.hpp>
|
||||
// other Linden headers
|
||||
#include "../test/lltut.h"
|
||||
|
||||
struct Data
|
||||
{
|
||||
Data(const std::string& data):
|
||||
mData(data)
|
||||
{}
|
||||
const std::string mData;
|
||||
};
|
||||
|
||||
void setter(Data** dest, Data* ptr)
|
||||
{
|
||||
*dest = ptr;
|
||||
}
|
||||
|
||||
static Data* static_check = 0;
|
||||
|
||||
// Set up an extern pointer to an LLPounceableStatic so the linker will fill
|
||||
// in the forward reference from below, before runtime.
|
||||
extern LLPounceable<Data*, LLPounceableStatic> gForward;
|
||||
|
||||
struct EnqueueCall
|
||||
{
|
||||
EnqueueCall()
|
||||
{
|
||||
// Intentionally use a forward reference to an LLPounceableStatic that
|
||||
// we believe is NOT YET CONSTRUCTED. This models the scenario in
|
||||
// which a constructor in another translation unit runs before
|
||||
// constructors in this one. We very specifically want callWhenReady()
|
||||
// to work even in that case: we need the LLPounceableQueueImpl to be
|
||||
// initialized even if the LLPounceable itself is not.
|
||||
gForward.callWhenReady(boost::bind(setter, &static_check, _1));
|
||||
}
|
||||
} nqcall;
|
||||
// When this declaration is processed, we should enqueue the
|
||||
// setter(&static_check, _1) call for when gForward is set non-NULL. Needless
|
||||
// to remark, we want this call not to crash.
|
||||
|
||||
// Now declare gForward. Its constructor should not run until after nqcall's.
|
||||
LLPounceable<Data*, LLPounceableStatic> gForward;
|
||||
|
||||
/*****************************************************************************
|
||||
* TUT
|
||||
*****************************************************************************/
|
||||
namespace tut
|
||||
{
|
||||
struct llpounceable_data
|
||||
{
|
||||
};
|
||||
typedef test_group<llpounceable_data> llpounceable_group;
|
||||
typedef llpounceable_group::object object;
|
||||
llpounceable_group llpounceablegrp("llpounceable");
|
||||
|
||||
template<> template<>
|
||||
void object::test<1>()
|
||||
{
|
||||
set_test_name("LLPounceableStatic out-of-order test");
|
||||
// LLPounceable<T, LLPounceableStatic>::callWhenReady() must work even
|
||||
// before LLPounceable's constructor runs. That's the whole point of
|
||||
// implementing it with an LLSingleton queue. This models (say)
|
||||
// LLPounceableStatic<LLMessageSystem*, LLPounceableStatic>.
|
||||
ensure("static_check should still be null", ! static_check);
|
||||
Data myData("test<1>");
|
||||
gForward = &myData; // should run setter
|
||||
ensure_equals("static_check should be &myData", static_check, &myData);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<2>()
|
||||
{
|
||||
set_test_name("LLPounceableQueue different queues");
|
||||
// We expect that LLPounceable<T, LLPounceableQueue> should have
|
||||
// different queues because that specialization stores the queue
|
||||
// directly in the LLPounceable instance.
|
||||
Data *aptr = 0, *bptr = 0;
|
||||
LLPounceable<Data*> a, b;
|
||||
a.callWhenReady(boost::bind(setter, &aptr, _1));
|
||||
b.callWhenReady(boost::bind(setter, &bptr, _1));
|
||||
ensure("aptr should be null", ! aptr);
|
||||
ensure("bptr should be null", ! bptr);
|
||||
Data adata("a"), bdata("b");
|
||||
a = &adata;
|
||||
ensure_equals("aptr should be &adata", aptr, &adata);
|
||||
// but we haven't yet set b
|
||||
ensure("bptr should still be null", !bptr);
|
||||
b = &bdata;
|
||||
ensure_equals("bptr should be &bdata", bptr, &bdata);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<3>()
|
||||
{
|
||||
set_test_name("LLPounceableStatic different queues");
|
||||
// LLPounceable<T, LLPounceableStatic> should also have a distinct
|
||||
// queue for each instance, but that engages an additional map lookup
|
||||
// because there's only one LLSingleton for each T.
|
||||
Data *aptr = 0, *bptr = 0;
|
||||
LLPounceable<Data*, LLPounceableStatic> a, b;
|
||||
a.callWhenReady(boost::bind(setter, &aptr, _1));
|
||||
b.callWhenReady(boost::bind(setter, &bptr, _1));
|
||||
ensure("aptr should be null", ! aptr);
|
||||
ensure("bptr should be null", ! bptr);
|
||||
Data adata("a"), bdata("b");
|
||||
a = &adata;
|
||||
ensure_equals("aptr should be &adata", aptr, &adata);
|
||||
// but we haven't yet set b
|
||||
ensure("bptr should still be null", !bptr);
|
||||
b = &bdata;
|
||||
ensure_equals("bptr should be &bdata", bptr, &bdata);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<4>()
|
||||
{
|
||||
set_test_name("LLPounceable<T> looks like T");
|
||||
// We want LLPounceable<T, TAG> to be drop-in replaceable for a plain
|
||||
// T for read constructs. In particular, it should behave like a dumb
|
||||
// pointer -- and with zero abstraction cost for such usage.
|
||||
Data* aptr = 0;
|
||||
Data a("a");
|
||||
// should be able to initialize a pounceable (when its constructor
|
||||
// runs)
|
||||
LLPounceable<Data*> pounceable = &a;
|
||||
// should be able to pass LLPounceable<T> to function accepting T
|
||||
setter(&aptr, pounceable);
|
||||
ensure_equals("aptr should be &a", aptr, &a);
|
||||
// should be able to dereference with *
|
||||
ensure_equals("deref with *", (*pounceable).mData, "a");
|
||||
// should be able to dereference with ->
|
||||
ensure_equals("deref with ->", pounceable->mData, "a");
|
||||
// bool operations
|
||||
ensure("test with operator bool()", pounceable);
|
||||
ensure("test with operator !()", ! (! pounceable));
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<5>()
|
||||
{
|
||||
set_test_name("Multiple callWhenReady() queue items");
|
||||
Data *p1 = 0, *p2 = 0, *p3 = 0;
|
||||
Data a("a");
|
||||
LLPounceable<Data*> pounceable;
|
||||
// queue up a couple setter() calls for later
|
||||
pounceable.callWhenReady(boost::bind(setter, &p1, _1));
|
||||
pounceable.callWhenReady(boost::bind(setter, &p2, _1));
|
||||
// should still be pending
|
||||
ensure("p1 should be null", !p1);
|
||||
ensure("p2 should be null", !p2);
|
||||
ensure("p3 should be null", !p3);
|
||||
pounceable = 0;
|
||||
// assigning a new empty value shouldn't flush the queue
|
||||
ensure("p1 should still be null", !p1);
|
||||
ensure("p2 should still be null", !p2);
|
||||
ensure("p3 should still be null", !p3);
|
||||
// using whichever syntax
|
||||
pounceable.reset(0);
|
||||
// try to make ensure messages distinct... tough to pin down which
|
||||
// ensure() failed if multiple ensure() calls in the same test<n> have
|
||||
// the same message!
|
||||
ensure("p1 should again be null", !p1);
|
||||
ensure("p2 should again be null", !p2);
|
||||
ensure("p3 should again be null", !p3);
|
||||
pounceable.reset(&a); // should flush queue
|
||||
ensure_equals("p1 should be &a", p1, &a);
|
||||
ensure_equals("p2 should be &a", p2, &a);
|
||||
ensure("p3 still not set", !p3);
|
||||
// immediate call
|
||||
pounceable.callWhenReady(boost::bind(setter, &p3, _1));
|
||||
ensure_equals("p3 should be &a", p3, &a);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<6>()
|
||||
{
|
||||
set_test_name("compile-fail test, uncomment to check");
|
||||
// The following declaration should fail: only LLPounceableQueue and
|
||||
// LLPounceableStatic should work as tags.
|
||||
// LLPounceable<Data*, int> pounceable;
|
||||
}
|
||||
} // namespace tut
|
||||
|
|
@ -65,7 +65,6 @@ namespace tut
|
|||
|
||||
//Delete the instance
|
||||
LLSingletonTest::deleteSingleton();
|
||||
ensure(LLSingletonTest::destroyed());
|
||||
ensure(!LLSingletonTest::instanceExists());
|
||||
|
||||
//Construct it again.
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "test_httprequestqueue.hpp"
|
||||
|
||||
#include "llproxy.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
unsigned long ssl_thread_id_callback(void);
|
||||
void ssl_locking_callback(int mode, int type, const char * file, int line);
|
||||
|
|
@ -101,7 +102,7 @@ void init_curl()
|
|||
|
||||
void term_curl()
|
||||
{
|
||||
LLProxy::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLProxy);
|
||||
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for (int i(0); i < ssl_mutex_count; ++i)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "llhttpclient.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llproxy.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
LLPumpIO* gServicePump = NULL;
|
||||
BOOL gBreak = false;
|
||||
|
|
@ -587,5 +588,5 @@ bool LLCrashLogger::init()
|
|||
void LLCrashLogger::commonCleanup()
|
||||
{
|
||||
LLError::logToFile(""); //close crashreport.log
|
||||
LLProxy::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLProxy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
#include "v3math.h"
|
||||
#include "v4math.h"
|
||||
#include "lltransfertargetvfile.h"
|
||||
#include "llpounceable.h"
|
||||
|
||||
// Constants
|
||||
//const char* MESSAGE_LOG_FILENAME = "message.log";
|
||||
|
|
@ -1776,7 +1777,9 @@ std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg)
|
|||
return s;
|
||||
}
|
||||
|
||||
LLMessageSystem *gMessageSystem = NULL;
|
||||
// LLPounceable supports callWhenReady(), to permit clients to queue up (e.g.)
|
||||
// callback registrations for when gMessageSystem is first assigned
|
||||
LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
|
||||
|
||||
// update appropriate ping info
|
||||
void process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/)
|
||||
|
|
@ -2693,7 +2696,7 @@ void end_messaging_system(bool print_summary)
|
|||
LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL;
|
||||
}
|
||||
|
||||
delete gMessageSystem;
|
||||
delete static_cast<LLMessageSystem*>(gMessageSystem);
|
||||
gMessageSystem = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include "llmessagesenderinterface.h"
|
||||
|
||||
#include "llstoredmessage.h"
|
||||
#include "llpounceable.h"
|
||||
|
||||
const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
|
||||
const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
|
||||
|
|
@ -830,7 +831,7 @@ private:
|
|||
|
||||
|
||||
// external hook into messaging system
|
||||
extern LLMessageSystem *gMessageSystem;
|
||||
extern LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
|
||||
|
||||
// Must specific overall system version, which is used to determine
|
||||
// if a patch is available in the message template checksum verification.
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "lliosocket.h"
|
||||
#include "stringize.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
namespace tut
|
||||
{
|
||||
|
|
@ -66,7 +67,7 @@ namespace tut
|
|||
~HTTPClientTestData()
|
||||
{
|
||||
delete mClientPump;
|
||||
LLProxy::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLProxy);
|
||||
apr_pool_destroy(mPool);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,11 +31,12 @@
|
|||
#include "llhost.h"
|
||||
#include "message.h"
|
||||
#include "llsd.h"
|
||||
#include "llpounceable.h"
|
||||
|
||||
#include "llhost.cpp" // Needed for copy operator
|
||||
#include "net.cpp" // Needed by LLHost.
|
||||
|
||||
LLMessageSystem * gMessageSystem = NULL;
|
||||
LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
|
||||
|
||||
// sensor test doubles
|
||||
bool gClearRecvWasCalled = false;
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@
|
|||
#include "message.h"
|
||||
#include "llmessageconfig.h"
|
||||
#include "llhttpnode_stub.cpp"
|
||||
#include "llpounceable.h"
|
||||
|
||||
LLMessageSystem* gMessageSystem = NULL;
|
||||
LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
|
||||
|
||||
LLMessageConfig::SenderTrust
|
||||
LLMessageConfig::getSenderTrustedness(const std::string& msg_name)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include "llflyoutbutton.h"
|
||||
#include "llsearcheditor.h"
|
||||
#include "lltoolbar.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
// for XUIParse
|
||||
#include "llquaternion.h"
|
||||
|
|
@ -208,7 +209,7 @@ void LLUI::initClass(const settings_map_t& settings,
|
|||
|
||||
void LLUI::cleanupClass()
|
||||
{
|
||||
LLRender2D::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLRender2D);
|
||||
}
|
||||
|
||||
void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llcachename.h"
|
||||
#include "lluuid.h"
|
||||
#include "message.h"
|
||||
#include "llpounceable.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -167,7 +168,7 @@ char const* const _PREHASH_AgentID = (char *)"AgentID";
|
|||
|
||||
LLHost LLHost::invalid(INVALID_PORT,INVALID_HOST_IP_ADDRESS);
|
||||
|
||||
LLMessageSystem* gMessageSystem = NULL;
|
||||
LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
|
||||
|
||||
//
|
||||
// Stub implementation for LLMessageSystem
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ int yyerror(const char *fmt, ...);
|
|||
"event" { count(); return(EVENT); }
|
||||
"jump" { count(); return(JUMP); }
|
||||
"return" { count(); return(RETURN); }
|
||||
"if" { count(); return(IF); }
|
||||
"if" { count(); return(IFF); }
|
||||
"else" { count(); return(ELSE); }
|
||||
"for" { count(); return(FOR); }
|
||||
"do" { count(); return(DO); }
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@
|
|||
%token SHIFT_LEFT
|
||||
%token SHIFT_RIGHT
|
||||
|
||||
%token IF
|
||||
%token IFF /* IF used by a helper library */
|
||||
%token ELSE
|
||||
%token FOR
|
||||
%token DO
|
||||
|
|
@ -1312,13 +1312,13 @@ statement
|
|||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| IF '(' expression ')' statement %prec LOWER_THAN_ELSE
|
||||
| IFF '(' expression ')' statement %prec LOWER_THAN_ELSE
|
||||
{
|
||||
$$ = new LLScriptIf(gLine, gColumn, $3, $5);
|
||||
$5->mAllowDeclarations = FALSE;
|
||||
gAllocationManager->addAllocation($$);
|
||||
}
|
||||
| IF '(' expression ')' statement ELSE statement
|
||||
| IFF '(' expression ')' statement ELSE statement
|
||||
{
|
||||
$$ = new LLScriptIfElse(gLine, gColumn, $3, $5, $7);
|
||||
$5->mAllowDeclarations = FALSE;
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@
|
|||
#include "llsecapi.h"
|
||||
#include "llmachineid.h"
|
||||
#include "llmainlooprepeater.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
|
||||
#include "llviewereventrecorder.h"
|
||||
|
|
@ -1764,7 +1765,7 @@ bool LLAppViewer::cleanup()
|
|||
gTransferManager.cleanup();
|
||||
#endif
|
||||
|
||||
LLLocalBitmapMgr::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLLocalBitmapMgr);
|
||||
|
||||
// Note: this is where gWorldMap used to be deleted.
|
||||
|
||||
|
|
@ -1872,11 +1873,11 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
LLViewerObject::cleanupVOClasses();
|
||||
|
||||
LLAvatarAppearance::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
|
||||
|
||||
LLAvatarAppearance::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
|
||||
|
||||
LLPostProcess::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLPostProcess);
|
||||
|
||||
LLTracker::cleanupInstance();
|
||||
|
||||
|
|
@ -1902,12 +1903,12 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
//end_messaging_system();
|
||||
|
||||
LLFollowCamMgr::cleanupClass();
|
||||
//LLVolumeMgr::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLFollowCamMgr);
|
||||
//SUBSYSTEM_CLEANUP(LLVolumeMgr);
|
||||
LLPrimitive::cleanupVolumeManager();
|
||||
LLWorldMapView::cleanupClass();
|
||||
LLFolderViewItem::cleanupClass();
|
||||
LLUI::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLWorldMapView);
|
||||
SUBSYSTEM_CLEANUP(LLFolderViewItem);
|
||||
SUBSYSTEM_CLEANUP(LLUI);
|
||||
|
||||
//
|
||||
// Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles).
|
||||
|
|
@ -1916,7 +1917,7 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
//
|
||||
LL_INFOS() << "Cleaning up VFS" << LL_ENDL;
|
||||
LLVFile::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLVFile);
|
||||
|
||||
LL_INFOS() << "Saving Data" << LL_ENDL;
|
||||
|
||||
|
|
@ -2020,7 +2021,7 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
// *NOTE:Mani - The following call is not thread safe.
|
||||
LL_CHECK_MEMORY
|
||||
LLCurl::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLCurl);
|
||||
LL_CHECK_MEMORY
|
||||
|
||||
// Non-LLCurl libcurl library
|
||||
|
|
@ -2029,9 +2030,9 @@ bool LLAppViewer::cleanup()
|
|||
// NOTE The following call is not thread safe.
|
||||
ll_cleanup_ares();
|
||||
|
||||
LLFilePickerThread::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLFilePickerThread);
|
||||
|
||||
//MUST happen AFTER LLCurl::cleanupClass
|
||||
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
|
||||
delete sTextureCache;
|
||||
sTextureCache = NULL;
|
||||
delete sTextureFetch;
|
||||
|
|
@ -2060,17 +2061,17 @@ bool LLAppViewer::cleanup()
|
|||
LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL;
|
||||
|
||||
//Note:
|
||||
//LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
|
||||
//SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown()
|
||||
//because some new image might be generated during cleaning up media. --bao
|
||||
LLViewerMedia::cleanupClass();
|
||||
LLViewerParcelMedia::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLViewerMedia);
|
||||
SUBSYSTEM_CLEANUP(LLViewerParcelMedia);
|
||||
gTextureList.shutdown(); // shutdown again in case a callback added something
|
||||
LLUIImageList::getInstance()->cleanUp();
|
||||
|
||||
// This should eventually be done in LLAppViewer
|
||||
LLImage::cleanupClass();
|
||||
LLVFSThread::cleanupClass();
|
||||
LLLFSThread::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLImage);
|
||||
SUBSYSTEM_CLEANUP(LLVFSThread);
|
||||
SUBSYSTEM_CLEANUP(LLLFSThread);
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
LL_INFOS() << "Auditing VFS" << LL_ENDL;
|
||||
|
|
@ -2113,9 +2114,9 @@ bool LLAppViewer::cleanup()
|
|||
LL_INFOS() << "File launched." << LL_ENDL;
|
||||
}
|
||||
LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
|
||||
LLProxy::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLProxy);
|
||||
|
||||
LLWearableType::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLWearableType);
|
||||
|
||||
LLMainLoopRepeater::instance().stop();
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
|
|||
gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
|
||||
gSavedPerAccountSettings.setBOOL("ConversationsParticipantListCollapsed", !isParticipantListExpanded());
|
||||
|
||||
if (!LLSingleton<LLIMMgr>::destroyed())
|
||||
if (LLIMMgr::instanceExists())
|
||||
{
|
||||
LLIMMgr::getInstance()->removeSessionObserver(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ LLMuteList* LLMuteList::getInstance()
|
|||
{
|
||||
// Register callbacks at the first time that we find that the message system has been created.
|
||||
static BOOL registered = FALSE;
|
||||
if( !registered && gMessageSystem != NULL)
|
||||
if( !registered && gMessageSystem)
|
||||
{
|
||||
registered = TRUE;
|
||||
// Register our various callbacks
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@
|
|||
#include "llevents.h"
|
||||
#include "llstartuplistener.h"
|
||||
#include "lltoolbarview.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include "lldxhardware.h"
|
||||
|
|
@ -2826,7 +2827,7 @@ void LLStartUp::initNameCache()
|
|||
|
||||
void LLStartUp::cleanupNameCache()
|
||||
{
|
||||
LLAvatarNameCache::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLAvatarNameCache);
|
||||
|
||||
delete gCacheName;
|
||||
gCacheName = NULL;
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@
|
|||
#include "llpathfindingmanager.h"
|
||||
#include "llstartup.h"
|
||||
#include "boost/unordered_map.hpp"
|
||||
#include "llcleanup.h"
|
||||
|
||||
using namespace LLAvatarAppearanceDefines;
|
||||
|
||||
|
|
@ -8416,7 +8417,7 @@ class LLWorldPostProcess : public view_listener_t
|
|||
|
||||
void handle_flush_name_caches()
|
||||
{
|
||||
LLAvatarNameCache::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLAvatarNameCache);
|
||||
if (gCacheName) gCacheName->clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@
|
|||
#include "llmediaentry.h"
|
||||
#include "llfloaterperms.h"
|
||||
#include "llvocache.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
//#define DEBUG_UPDATE_TYPE
|
||||
|
||||
|
|
@ -527,11 +528,11 @@ void LLViewerObject::initVOClasses()
|
|||
|
||||
void LLViewerObject::cleanupVOClasses()
|
||||
{
|
||||
LLVOGrass::cleanupClass();
|
||||
LLVOWater::cleanupClass();
|
||||
LLVOTree::cleanupClass();
|
||||
LLVOAvatar::cleanupClass();
|
||||
LLVOVolume::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLVOGrass);
|
||||
SUBSYSTEM_CLEANUP(LLVOWater);
|
||||
SUBSYSTEM_CLEANUP(LLVOTree);
|
||||
SUBSYSTEM_CLEANUP(LLVOAvatar);
|
||||
SUBSYSTEM_CLEANUP(LLVOVolume);
|
||||
|
||||
sObjectDataMap.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@
|
|||
#include "llwindowlistener.h"
|
||||
#include "llviewerwindowlistener.h"
|
||||
#include "llpaneltopinfobar.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include <tchar.h> // For Unicode conversion methods
|
||||
|
|
@ -2124,7 +2125,7 @@ void LLViewerWindow::shutdownGL()
|
|||
// Shutdown GL cleanly. Order is very important here.
|
||||
//--------------------------------------------------------
|
||||
LLFontGL::destroyDefaultFonts();
|
||||
LLFontManager::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLFontManager);
|
||||
stop_glerror();
|
||||
|
||||
gSky.cleanup();
|
||||
|
|
@ -2147,7 +2148,7 @@ void LLViewerWindow::shutdownGL()
|
|||
LLWorldMapView::cleanupTextures();
|
||||
|
||||
LLViewerTextureManager::cleanup() ;
|
||||
LLImageGL::cleanupClass() ;
|
||||
SUBSYSTEM_CLEANUP(LLImageGL) ;
|
||||
|
||||
LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ;
|
||||
|
||||
|
|
@ -2160,7 +2161,7 @@ void LLViewerWindow::shutdownGL()
|
|||
|
||||
gGL.shutdown();
|
||||
|
||||
LLVertexBuffer::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLVertexBuffer);
|
||||
|
||||
LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@
|
|||
#include "llpathfindingpathtool.h"
|
||||
#include "llscenemonitor.h"
|
||||
#include "llprogressview.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Debug indices is disabled for now for debug performance - djs 4/24/02
|
||||
|
|
@ -7373,7 +7374,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
|
|||
}
|
||||
LLVOPartGroup::destroyGL();
|
||||
|
||||
LLVertexBuffer::cleanupClass();
|
||||
SUBSYSTEM_CLEANUP(LLVertexBuffer);
|
||||
|
||||
//delete all name pool caches
|
||||
LLGLNamePool::cleanupPools();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "../llagent.h"
|
||||
#include "message.h"
|
||||
#include "llurlentry.h"
|
||||
#include "llpounceable.h"
|
||||
|
||||
namespace {
|
||||
const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");
|
||||
|
|
@ -61,7 +62,7 @@ void LLMessageSystem::addUUID(char const *,LLUUID const &) { }
|
|||
void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { }
|
||||
void LLMessageSystem::nextBlockFast(char const *) { }
|
||||
void LLMessageSystem::newMessage(char const *) { }
|
||||
LLMessageSystem * gMessageSystem;
|
||||
LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
|
||||
char const* const _PREHASH_AgentID = 0; // never dereferenced during this test
|
||||
char const* const _PREHASH_AgentData = 0; // never dereferenced during this test
|
||||
LLAgent gAgent;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ namespace tut
|
|||
~LLMessageSystemTestData()
|
||||
{
|
||||
// not end_messaging_system()
|
||||
delete gMessageSystem;
|
||||
delete static_cast<LLMessageSystem*>(gMessageSystem);
|
||||
gMessageSystem = NULL;
|
||||
|
||||
// rm contents of temp dir
|
||||
|
|
|
|||
Loading…
Reference in New Issue