Automated merge with ssh://bitbucket.org/lindenlab/viewer-release

meow-7.2.2
Nat Goodspeed 2015-05-26 20:15:42 -04:00
commit df55db4aa0
31 changed files with 528 additions and 71 deletions

View File

@ -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();

View File

@ -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)

View File

@ -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

View File

@ -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) */

View File

@ -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);
}

View File

@ -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) */

View File

@ -269,7 +269,7 @@ public:
~ScopedRegistrar()
{
if (!singleton_t::destroyed())
if (singleton_t::instanceExists())
{
popScope();
}

View File

@ -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:

View File

@ -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

View File

@ -65,7 +65,6 @@ namespace tut
//Delete the instance
LLSingletonTest::deleteSingleton();
ensure(LLSingletonTest::destroyed());
ensure(!LLSingletonTest::instanceExists());
//Construct it again.

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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);
}

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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); }

View File

@ -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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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 ;
}

View File

@ -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();

View File

@ -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;

View File

@ -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