diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llfile.cpp | 21 | ||||
| -rw-r--r-- | indra/llcommon/llsingleton.h | 101 | ||||
| -rw-r--r-- | indra/llcommon/llthread.h | 90 | ||||
| -rw-r--r-- | indra/llplugin/slplugin/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | indra/newview/llfloateravatarpicker.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 36 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
| -rwxr-xr-x | indra/newview/llviewerwindow.cpp | 4 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.cpp | 29 | 
9 files changed, 140 insertions, 162 deletions
| 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); | 
