summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.hgtags4
-rw-r--r--doc/contributions.txt2
-rw-r--r--indra/llcommon/llfile.cpp21
-rw-r--r--indra/llcommon/llsingleton.h101
-rw-r--r--indra/llcommon/llthread.h90
-rw-r--r--indra/llplugin/slplugin/CMakeLists.txt10
-rw-r--r--indra/newview/llfloateravatarpicker.cpp9
-rw-r--r--indra/newview/llviewerobject.cpp36
-rw-r--r--indra/newview/llviewerobject.h2
-rwxr-xr-xindra/newview/llviewerwindow.cpp4
-rwxr-xr-xindra/newview/llvoavatar.cpp29
11 files changed, 146 insertions, 162 deletions
diff --git a/.hgtags b/.hgtags
index 0f18172fe9..fece298a21 100755
--- a/.hgtags
+++ b/.hgtags
@@ -440,3 +440,7 @@ adc360e6bf21390d2665380951d85937cd29a604 3.5.0-release
1ada73295ed0eaa4a772ef079c29f57069342c32 DRTVWR-310
0ca3910763cec967703e45bc6208a325dccb9f95 3.5.1-beta1
20cdf370f5c8be6193bef6fb3a81cc3f81275191 3.5.1-beta1
+2319904200de367646b9a9442239a38d52c1eeb5 DRTVWR-313
+9d8726eca785acad694564516f16dd639faf45c0 3.5.1-beta2
+4b7fa963b80e2056ab648f83a4d61310b3cedb3d DRTVWR-314
+65ae89aeb7ea674a555e439e963f17949322ac94 3.5.1-beta3
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 3abf32b8b1..526cd4ea28 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -300,6 +300,7 @@ ChickyBabes Zuzu
Christopher Organiser
Ciaran Laval
Cinder Roxley
+ BUG-2326
STORM-1703
Clara Young
Coaldust Numbers
@@ -900,6 +901,7 @@ NickyD
Nicky Dasmijn
VWR-29228
MAINT-873
+ SUN-72
STORM-1935
STORM-1936
STORM-1937
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index bc615ed39e..864b6e6975 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -853,7 +853,8 @@ llifstream::llifstream(const std::string& _Filename,
#if LL_WINDOWS
std::istream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -872,7 +873,8 @@ llifstream::llifstream(const char* _Filename,
#if LL_WINDOWS
std::istream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -917,8 +919,10 @@ bool llifstream::is_open() const
void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
{ // open a C stream with specified mode
- if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+
#if LL_WINDOWS
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -927,6 +931,7 @@ void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
_Myios::clear();
}
#else
+ if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
{
this->setstate(ios_base::failbit);
}
@@ -969,7 +974,8 @@ llofstream::llofstream(const std::string& _Filename,
#if LL_WINDOWS
std::ostream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -988,7 +994,8 @@ llofstream::llofstream(const char* _Filename,
#if LL_WINDOWS
std::ostream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -1032,8 +1039,9 @@ bool llofstream::is_open() const
void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
{ // open a C stream with specified mode
- if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
#if LL_WINDOWS
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -1042,6 +1050,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
_Myios::clear();
}
#else
+ if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
{
this->setstate(ios_base::failbit);
}
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 550e3c0d20..40002313f1 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -61,6 +61,7 @@ class LLSingleton : private boost::noncopyable
private:
typedef enum e_init_state
{
+ UNINITIALIZED,
CONSTRUCTING,
INITIALIZING,
INITIALIZED,
@@ -68,23 +69,23 @@ private:
} EInitState;
// stores pointer to singleton instance
- // and tracks initialization state of singleton
- struct SingletonInstanceData
+ struct SingletonLifetimeManager
{
- EInitState mInitState;
- DERIVED_TYPE* mSingletonInstance;
-
- SingletonInstanceData()
- : mSingletonInstance(NULL),
- mInitState(CONSTRUCTING)
+ SingletonLifetimeManager()
+ {
+ construct();
+ }
+
+ static void construct()
{
- mSingletonInstance = new DERIVED_TYPE();
- mInitState = INITIALIZING;
+ sData.mInitState = CONSTRUCTING;
+ sData.mInstance = new DERIVED_TYPE();
+ sData.mInitState = INITIALIZING;
}
- ~SingletonInstanceData()
+ ~SingletonLifetimeManager()
{
- if (mInitState != DELETED)
+ if (sData.mInitState != DELETED)
{
deleteSingleton();
}
@@ -94,9 +95,8 @@ private:
public:
virtual ~LLSingleton()
{
- SingletonInstanceData& data = getData();
- data.mSingletonInstance = NULL;
- data.mInitState = DELETED;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
/**
@@ -121,42 +121,46 @@ public:
*/
static void deleteSingleton()
{
- delete getData().mSingletonInstance;
- getData().mSingletonInstance = NULL;
- getData().mInitState = DELETED;
+ delete sData.mInstance;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
- static SingletonInstanceData& getData()
- {
- // this is static to cache the lookup results
- static SingletonInstanceData sData;
- return sData;
- }
static DERIVED_TYPE* getInstance()
{
- SingletonInstanceData& data = getData();
+ static SingletonLifetimeManager sLifeTimeMgr;
- if (data.mInitState == CONSTRUCTING)
+ switch (sData.mInitState)
{
+ case UNINITIALIZED:
+ // should never be uninitialized at this point
+ llassert(false);
+ return NULL;
+ case CONSTRUCTING:
llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
- }
-
- if (data.mInitState == DELETED)
- {
- llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
- data.mSingletonInstance = new DERIVED_TYPE();
- data.mInitState = INITIALIZING;
- } // Fall into INITIALIZING case below
-
- if (data.mInitState == INITIALIZING)
- {
+ return NULL;
+ case INITIALIZING:
// go ahead and flag ourselves as initialized so we can be reentrant during initialization
- data.mInitState = INITIALIZED;
- data.mSingletonInstance->initSingleton();
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
+ case INITIALIZED:
+ return sData.mInstance;
+ case DELETED:
+ llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+ SingletonLifetimeManager::construct();
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
}
-
- return data.mSingletonInstance;
+
+ return NULL;
+ }
+
+ static DERIVED_TYPE* getIfExists()
+ {
+ return sData.mInstance;
}
// Reference version of getInstance()
@@ -170,18 +174,29 @@ public:
// Use this to avoid accessing singletons before the can safely be constructed
static bool instanceExists()
{
- return getData().mInitState == INITIALIZED;
+ 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 getData().mInitState == DELETED;
+ return sData.mInitState == DELETED;
}
private:
+
virtual void initSingleton() {}
+
+ struct SingletonData
+ {
+ EInitState mInitState;
+ DERIVED_TYPE* mInstance;
+ };
+ static SingletonData sData;
};
+template<typename T>
+typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
+
#endif
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index a6eb14db9d..f51d985b5f 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -225,7 +225,6 @@ void LLThread::unlockData()
// see llmemory.h for LLPointer<> definition
-#if (1) // Old code - see comment below
class LL_COMMON_API LLThreadSafeRefCount
{
public:
@@ -243,99 +242,28 @@ public:
LLThreadSafeRefCount(const LLThreadSafeRefCount&);
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
{
- if (sMutex)
- {
- sMutex->lock();
- }
mRef = 0;
- if (sMutex)
- {
- sMutex->unlock();
- }
return *this;
}
-
-
void ref()
{
- if (sMutex) sMutex->lock();
mRef++;
- if (sMutex) sMutex->unlock();
}
- S32 unref()
+ void unref()
{
llassert(mRef >= 1);
- if (sMutex) sMutex->lock();
- S32 res = --mRef;
- if (sMutex) sMutex->unlock();
- if (0 == res)
- {
- delete this;
- return 0;
+ if ((--mRef) == 0) // See note in llapr.h on atomic decrement operator return value.
+ {
+ // If we hit zero, the caller should be the only smart pointer owning the object and we can delete it.
+ // It is technically possible for a vanilla pointer to mess this up, or another thread to
+ // jump in, find this object, create another smart pointer and end up dangling, but if
+ // the code is that bad and not thread-safe, it's trouble already.
+ delete this;
}
- return res;
- }
- S32 getNumRefs() const
- {
- return mRef;
}
-private:
- S32 mRef;
-};
-
-#else
- // New code - This was from https://bitbucket.org/lindenlab/viewer-cat/commits/b03bb43e4ead57f904cb3c1e9745dc8460de6efc
- // and attempts
-
-class LL_COMMON_API LLThreadSafeRefCount
-{
-public:
- static void initThreadSafeRefCount(); // creates sMutex
- static void cleanupThreadSafeRefCount(); // destroys sMutex
-
-private:
- static LLMutex* sMutex;
-
-protected:
- virtual ~LLThreadSafeRefCount(); // use unref()
-
-public:
- LLThreadSafeRefCount();
- LLThreadSafeRefCount(const LLThreadSafeRefCount&);
- LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
- {
- mRef = 0;
- return *this;
- }
-
- void ref()
- {
- mRef++;
- }
-
- S32 unref()
- {
- llassert(mRef >= 1);
- bool time_to_die = (mRef == 1);
- if (time_to_die)
- {
- if (sMutex) sMutex->lock();
- // Looks redundant, but is very much not
- // We need to check again once we've acquired the lock
- // so that two threads who get into the if in parallel
- // don't both attempt to the delete.
- //
- mRef--; // Simon: why not if (mRef == 1) delete this; ? There still seems to be a window where mRef could be modified
- if (mRef == 0)
- delete this;
- if (sMutex) sMutex->unlock();
- return 0;
- }
- return --mRef;
- }
S32 getNumRefs() const
{
const S32 currentVal = mRef.CurrentValue();
@@ -345,7 +273,7 @@ public:
private:
LLAtomic32< S32 > mRef;
};
-#endif // new code
+
/**
* intrusive pointer support for LLThreadSafeRefCount
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 5d2b1d922e..6e7fefeb21 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -50,13 +50,17 @@ add_executable(SLPlugin
${SLPlugin_SOURCE_FILES}
)
+if (WINDOWS)
set_target_properties(SLPlugin
PROPERTIES
- MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
-if (WINDOWS)
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\""
-endif (WINDOWS)
)
+else ()
+set_target_properties(SLPlugin
+ PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
+ )
+endif ()
target_link_libraries(SLPlugin
${LLPLUGIN_LIBRARIES}
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 3e0e82b579..113aa9a8f2 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -818,7 +818,14 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled()
uuid_vec_t avatar_ids;
std::vector<LLAvatarName> avatar_names;
getSelectedAvatarData(list, avatar_ids, avatar_names);
- return mOkButtonValidateSignal(avatar_ids);
+ if (avatar_ids.size() >= 1)
+ {
+ ret_val = mOkButtonValidateSignal(avatar_ids);
+ }
+ else
+ {
+ ret_val = false;
+ }
}
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index ac517f1fb7..9dc9932c86 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2699,24 +2699,33 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
if(ft && (0 == error_code) &&
(object = gObjectList.findObject(ft->mTaskID)))
{
- object->loadTaskInvFile(ft->mFilename);
+ if (object->loadTaskInvFile(ft->mFilename))
+ {
- LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
- LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
- std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
+ LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
+ std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
- for (; it != end && pending_lst.size(); ++it)
- {
- LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
- if(item && item->getType() != LLAssetType::AT_CATEGORY)
+ for (; it != end && pending_lst.size(); ++it)
{
- std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
- if (id_it != pending_lst.end())
+ LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
+ if(item && item->getType() != LLAssetType::AT_CATEGORY)
{
- pending_lst.erase(id_it);
+ std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
+ if (id_it != pending_lst.end())
+ {
+ pending_lst.erase(id_it);
+ }
}
}
}
+ else
+ {
+ // MAINT-2597 - crash when trying to edit a no-mod object
+ // Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)
+ // Stated repro was specific to no-mod objects so failing without user interaction should be safe.
+ llwarns << "Trying to load invalid task inventory file. Ignoring file contents." << llendl;
+ }
}
else
{
@@ -2728,7 +2737,7 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
delete ft;
}
-void LLViewerObject::loadTaskInvFile(const std::string& filename)
+BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
{
std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
llifstream ifs(filename_and_local_path);
@@ -2775,8 +2784,11 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)
{
llwarns << "unable to load task inventory: " << filename_and_local_path
<< llendl;
+ return FALSE;
}
doInventoryCallback();
+
+ return TRUE;
}
void LLViewerObject::doInventoryCallback()
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 40e09a4f41..9996c916a4 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -651,7 +651,7 @@ protected:
//
static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
- void loadTaskInvFile(const std::string& filename);
+ BOOL loadTaskInvFile(const std::string& filename);
void doInventoryCallback();
BOOL isOnMap();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 136e61389a..c65caea3ec 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2036,8 +2036,8 @@ void LLViewerWindow::shutdownViews()
}
llinfos << "Global views cleaned." << llendl ;
- LLNotificationsUI::LLToast::cleanupToasts();
- llinfos << "Leftover toast cleaned up." << llendl;
+ LLNotificationsUI::LLToast::cleanupToasts();
+ llinfos << "Leftover toast cleaned up." << llendl;
// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
// will crump with LL_ERRS.
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a57679b71e..3c25339037 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -815,14 +815,14 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c
//------------------------------------------------------------------------
LLVOAvatar::~LLVOAvatar()
{
- if (!mFullyLoaded)
- {
+ if (!mFullyLoaded)
+ {
debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
- }
- else
- {
+ }
+ else
+ {
debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
- }
+ }
logPendingPhases();
@@ -6110,6 +6110,11 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
void LLVOAvatar::logPendingPhases()
{
+ if (!isAgentAvatarValid())
+ {
+ return;
+ }
+
for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();
it != getPhases().end();
++it)
@@ -6144,6 +6149,11 @@ void LLVOAvatar::logPendingPhasesAllAvatars()
void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
{
+ if (!isAgentAvatarValid())
+ {
+ return;
+ }
+
LLSD record;
record["timer_name"] = phase_name;
record["avatar_id"] = getID();
@@ -6160,13 +6170,6 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse
record["is_using_server_bakes"] = ((bool) isUsingServerBakes());
record["is_self"] = isSelf();
-
-#if 0 // verbose logging
- std::ostringstream ostr;
- ostr << LLSDNotationStreamer(record);
- LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl;
-#endif
-
if (isAgentAvatarValid())
{
gAgentAvatarp->addMetricsTimerRecord(record);