diff options
| author | Richard Linden <none@none> | 2013-06-21 11:00:47 -0700 | 
|---|---|---|
| committer | Richard Linden <none@none> | 2013-06-21 11:00:47 -0700 | 
| commit | 090fa057b5ff17170d846473a2bc9ebc315c99d3 (patch) | |
| tree | 781dff230ab8d1fc651e453cdd568df5aff8487a /indra/llcommon | |
| parent | 5de2f0a8970244866dc8b511caa3c8626955264f (diff) | |
| parent | a2a6bf20d71f923e9a5e43f71213fffbfea5a2a6 (diff) | |
merge
Diffstat (limited to 'indra/llcommon')
| -rwxr-xr-x | indra/llcommon/llapp.cpp | 4 | ||||
| -rwxr-xr-x | indra/llcommon/llapr.cpp | 8 | ||||
| -rwxr-xr-x | indra/llcommon/llavatarname.h | 2 | ||||
| -rwxr-xr-x | indra/llcommon/llcoros.cpp | 4 | ||||
| -rwxr-xr-x | indra/llcommon/llerror.cpp | 27 | ||||
| -rwxr-xr-x | indra/llcommon/llerror.h | 13 | ||||
| -rwxr-xr-x | indra/llcommon/llerrorlegacy.h | 8 | ||||
| -rwxr-xr-x | indra/llcommon/llfasttimer.cpp | 46 | ||||
| -rwxr-xr-x | indra/llcommon/llfile.cpp | 2 | ||||
| -rwxr-xr-x | indra/llcommon/llfile.h | 4 | ||||
| -rwxr-xr-x | indra/llcommon/llsdserialize_xml.cpp | 4 | ||||
| -rw-r--r-- | indra/llcommon/lltracerecording.cpp | 58 | ||||
| -rw-r--r-- | indra/llcommon/llunit.h | 17 | ||||
| -rwxr-xr-x | indra/llcommon/tests/llprocess_test.cpp | 5 | 
14 files changed, 119 insertions, 83 deletions
| diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index c6da205815..67a98d5fb8 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -986,9 +986,9 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,  	}  	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; -    // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. +   // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.  	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); -    // *TODO: Translate the signals/exceptions into cross-platform stuff +   // *TODO: Translate the signals/exceptions into cross-platform stuff  	// Windows implementation  	llinfos << "Entering Windows Exception Handler..." << llendl; diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 47fa70614f..b6adb37eba 100755 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -56,7 +56,7 @@ void ll_init_apr()  	if(!LLAPRFile::sAPRFilePoolp)  	{ -		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE); +		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;  	}  	LLThreadLocalPointerBase::initAllThreadLocalStorage(); @@ -101,7 +101,7 @@ void ll_cleanup_apr()  	}  	if (LLAPRFile::sAPRFilePoolp)  	{ -		delete LLAPRFile::sAPRFilePoolp ;	 +		delete LLAPRFile::sAPRFilePoolp ;  		LLAPRFile::sAPRFilePoolp = NULL ;  	}  	apr_terminate(); @@ -243,9 +243,7 @@ void LLVolatileAPRPool::clearVolatileAPRPool()  		llassert_always(mNumActiveRef > 0) ;  	} -	//paranoia check if the pool is jammed. -	//will remove the check before going to release. -	llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; +	llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;  }  BOOL LLVolatileAPRPool::isFull() diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 7542a8dece..5d2fccc5ba 100755 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -63,7 +63,7 @@ public:  	// For normal names, returns "James Linden (james.linden)"  	// When display names are disabled returns just "James Linden"  	std::string getCompleteName() const; - +	  	// Returns "James Linden" or "bobsmith123 Resident" for backwards  	// compatibility with systems like voice and muting  	// *TODO: Eliminate this in favor of username only diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index a629f71d4b..baaddcaed1 100755 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -60,7 +60,7 @@ bool LLCoros::cleanup(const LLSD&)          // since last tick?          if (mi->second->exited())          { -            LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL; +			   LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;              // The erase() call will invalidate its passed iterator value --              // so increment mi FIRST -- but pass its original value to              // erase(). This is what postincrement is all about. @@ -94,7 +94,7 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const      {          if (mCoros.find(name) == mCoros.end())          { -            LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL; +			   LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;              return name;          }      } diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 9b0141eb76..d2af004cde 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -201,10 +201,7 @@ namespace {  		virtual void recordMessage(LLError::ELevel level,  								   const std::string& message)  		{ -			llutf16string utf16str = -				wstring_to_utf16str(utf8str_to_wstring(message)); -			utf16str += '\n'; -			OutputDebugString(utf16str.c_str()); +			LL_WINDOWS_OUTPUT_DEBUG(message);  		}  	};  #endif @@ -1401,5 +1398,27 @@ namespace LLError     {         sIndex = 0 ;     } + +#if LL_WINDOWS +	void LLOutputDebugUTF8(const std::string& s) +	{ +		// Be careful when calling OutputDebugString as it throws DBG_PRINTEXCEPTION_C  +		// which works just fine under the windows debugger, but can cause users who +		// have enabled SEHOP exception chain validation to crash due to interactions +		// between the Win 32-bit exception handling and boost coroutine fiber stacks. BUG-2707 +		// +		if (IsDebuggerPresent()) +		{ +			// Need UTF16 for Unicode OutputDebugString +			// +			if (s.size()) +			{ +				OutputDebugString(utf8str_to_utf16str(s).c_str()); +				OutputDebugString(TEXT("\n")); +			} +		} +	} +#endif +  } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index b65b410153..0b723aeb5d 100755 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -34,7 +34,6 @@  #include "llerrorlegacy.h"  #include "stdtypes.h" -  /** Error Logging Facility  	Information for most users: @@ -199,8 +198,20 @@ namespace LLError         static void clear() ;  	   static void end(std::ostringstream* _out) ;     };  + +#if LL_WINDOWS +	void LLOutputDebugUTF8(const std::string& s); +#endif +  } +#if LL_WINDOWS +	// Macro accepting a std::string for display in windows debugging console +	#define LL_WINDOWS_OUTPUT_DEBUG(a) LLError::LLOutputDebugUTF8(a) +#else +	#define LL_WINDOWS_OUTPUT_DEBUG(a) +#endif +  //this is cheaper than llcallstacks if no need to output other variables to call stacks.   #define llpushcallstacks LLError::LLCallStacks::push(__FUNCTION__, __LINE__)  #define llcallstacks \ diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h index 097a533b1a..50c95339e4 100755 --- a/indra/llcommon/llerrorlegacy.h +++ b/indra/llcommon/llerrorlegacy.h @@ -113,11 +113,11 @@ const int LL_ERR_PRICE_MISMATCH = -23018;  #endif  #ifdef LL_WINDOWS -#define llstatic_assert(func, msg) static_assert(func, msg) -#define llstatic_assert_template(type, func, msg) static_assert(func, msg) +#define LL_STATIC_ASSERT(func, msg) static_assert(func, msg) +#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(false, msg)  #else -#define llstatic_assert(func, msg) BOOST_STATIC_ASSERT(func) -#define llstatic_assert_template(type, func, msg) BOOST_STATIC_ASSERT(sizeof(type) != 0 && func); +#define LL_STATIC_ASSERT(func, msg) BOOST_STATIC_ASSERT(func) +#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) BOOST_STATIC_ASSERT(sizeof(type) != 0 && false);  #endif  // handy compile-time assert - enforce those template parameters!  diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index becfa9c288..60c451b137 100755 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -130,9 +130,9 @@ void TimeBlock::pushLog(LLSD log)  	}  void TimeBlock::setLogLock(LLMutex* lock) -{ +	{  	sLogLock = lock; -} +	}  //static @@ -182,7 +182,7 @@ void TimeBlock::bootstrapTimerTree()  	for (LLInstanceTracker<TimeBlock>::instance_iter begin_it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances(), it = begin_it;   		it != end_it;   		++it) -	{ +		{  		TimeBlock& timer = *it;  		if (&timer == &TimeBlock::getRootTimeBlock()) continue; @@ -193,13 +193,13 @@ void TimeBlock::bootstrapTimerTree()  			TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();  			if (accumulator->mLastCaller) -			{ +	{  				timer.setParent(accumulator->mLastCaller);  				accumulator->mParent = accumulator->mLastCaller; -			} +	}  			// no need to push up tree on first use, flag can be set spuriously  			accumulator->mMoveUpTree = false; -		} +}  	}  } @@ -217,37 +217,37 @@ void TimeBlock::incrementalUpdateTimerTree()  		// sort timers by time last called, so call graph makes sense  		TimeBlockTreeNode& tree_node = timerp->getTreeNode();  		if (tree_node.mNeedsSorting) -		{ +			{  			std::sort(tree_node.mChildren.begin(), tree_node.mChildren.end(), SortTimerByName()); -		} +	}  		// skip root timer  		if (timerp != &TimeBlock::getRootTimeBlock()) -		{ +	{  			TimeBlockAccumulator* accumulator = timerp->getPrimaryAccumulator();  			if (accumulator->mMoveUpTree) -			{ +		{  				// since ancestors have already been visited, re-parenting won't affect tree traversal -				//step up tree, bringing our descendants with us -				LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << -					" to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL; -				timerp->setParent(timerp->getParent()->getParent()); +			//step up tree, bringing our descendants with us +			LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << +				" to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL; +			timerp->setParent(timerp->getParent()->getParent());  				accumulator->mParent = timerp->getParent();  				accumulator->mMoveUpTree = false; -				// don't bubble up any ancestors until descendants are done bubbling up +			// don't bubble up any ancestors until descendants are done bubbling up  				// as ancestors may call this timer only on certain paths, so we want to resolve  				// child-most block locations before their parents -				it.skipAncestors(); -			} +			it.skipAncestors();  		}  	} +	}  }  void TimeBlock::updateTimes() -{ +	{  	U64 cur_time = getCPUClockCount64();  	// walk up stack of active timers and accumulate current time while leaving timing structures active @@ -257,7 +257,7 @@ void TimeBlock::updateTimes()  	while(cur_timer   		&& cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self -	{ +		{  		U64 cumulative_time_delta = cur_time - cur_timer->mStartTime;  		accumulator->mTotalTimeCounter += cumulative_time_delta   			- (accumulator->mTotalTimeCounter  @@ -307,12 +307,12 @@ void TimeBlock::processTimes()  }  std::vector<TimeBlock*>::iterator TimeBlock::beginChildren() -{ +		{  	return getTreeNode().mChildren.begin();  -} +		}  std::vector<TimeBlock*>::iterator TimeBlock::endChildren() -{ +		{  	return getTreeNode().mChildren.end();  } @@ -372,7 +372,7 @@ void TimeBlock::logStats()  //static  void TimeBlock::dumpCurTimes() -{ +	{  	LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording();  	LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 40a57c2ae4..06bc931dea 100755 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -848,7 +848,7 @@ llifstream::llifstream() : _M_filebuf(),  #endif  // explicit -llifstream::llifstream(const std::string& _Filename, +llifstream::llifstream(const std::string& _Filename,   		ios_base::openmode _Mode) : _M_filebuf(),  #if LL_WINDOWS  	std::istream(&_M_filebuf) diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 9d70db96ea..d59e68367e 100755 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -35,7 +35,7 @@   * Attempts to mostly mirror the POSIX style IO functions.   */ -typedef FILE LLFILE; +typedef FILE	LLFILE;  #include <fstream>  #include <sys/stat.h> @@ -237,7 +237,7 @@ public:  			ios_base::openmode _Mode = ios_base::in,  			//size_t _Size = static_cast<size_t>(BUFSIZ));  			size_t _Size = static_cast<size_t>(1)); - +	  	/**  	 *  @brief  Create a stream using an open file descriptor.  	 *  @param  fd    An open file descriptor. diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index cef743a7be..614a2d5636 100755 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -406,7 +406,7 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)  		}  		if (mEmitErrors)  		{ -			llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl; +		llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;  		}  		data = LLSD();  		return LLSDParser::PARSE_FAILURE; @@ -487,7 +487,7 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)  	{  		if (mEmitErrors)  		{ -			llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl; +		llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;  		}  		return LLSDParser::PARSE_FAILURE;  	} diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 52ecb463be..ff1589d12d 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -429,36 +429,49 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )  	getCurRecording().update();  	other.getCurRecording().update(); +	 +	const U32 other_recording_slots = other.mRecordingPeriods.size(); +	const U32 other_num_recordings = other.getNumRecordedPeriods(); +	const U32 other_current_recording_index = other.mCurPeriod; +	const U32 other_oldest_recording_index = (other_current_recording_index + other_recording_slots - other_num_recordings + 1) % other_recording_slots; + +	// append first recording into our current slot +	getCurRecording().appendRecording(other.mRecordingPeriods[other_oldest_recording_index]); + +	// from now on, add new recordings for everything after the first +	U32 other_index = (other_oldest_recording_index + 1) % other_recording_slots;  	if (mAutoResize)  	{ -		S32 other_index = (other.mCurPeriod + 1) % other.mRecordingPeriods.size(); -		S32 end_index = (other.mCurPeriod) % other.mRecordingPeriods.size();  +		// append first recording into our current slot +		getCurRecording().appendRecording(other.mRecordingPeriods[other_oldest_recording_index]); -		do +		// push back recordings for everything in the middle +		U32 other_index = (other_oldest_recording_index + 1) % other_recording_slots; +		while (other_index != other_current_recording_index)  		{ -			if (other.mRecordingPeriods[other_index].getDuration().value()) -			{ -				mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]); -			} -			other_index = (other_index + 1) % other.mRecordingPeriods.size(); +			mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]); +			other_index = (other_index + 1) % other_recording_slots; +		} + +		// add final recording, if it wasn't already added as the first +		if (other_num_recordings > 1) +		{ +			mRecordingPeriods.push_back(other.mRecordingPeriods[other_current_recording_index]);  		} -		while(other_index != end_index);  		mCurPeriod = mRecordingPeriods.size() - 1;  		mNumPeriods = mRecordingPeriods.size();  	}  	else  	{ -		//FIXME: get proper number of recordings from other...might not have used all its slots -		size_t num_to_copy = llmin(	mRecordingPeriods.size(), other.getNumRecordedPeriods()); -		std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin()  -													+ (	(other.mCurPeriod + 1									// oldest period -															+ (other.mRecordingPeriods.size() - num_to_copy))	// minus room for copy -														% other.mRecordingPeriods.size()); +		size_t num_to_copy = llmin(	mRecordingPeriods.size(), (size_t)other_num_recordings); + +		std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin() + other_index ;  		std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + mCurPeriod; -		for(size_t i = 0; i < num_to_copy; i++) +		// already consumed the first recording from other, so start counting at 1 +		for(size_t i = 1; i < num_to_copy; i++)  		{  			*dest_it = *src_it; @@ -475,17 +488,14 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )  		// want argument to % to be positive, otherwise result could be negative and thus out of bounds  		llassert(num_to_copy >= 1); -		// advance to last recording period copied, so we can check if the last period had actually carried any data, in which case we'll advance below -		// using nextPeriod() which retains continuity (mLastValue, etc) +		// advance to last recording period copied, and make that our current period  		mCurPeriod = (mCurPeriod + num_to_copy - 1) % mRecordingPeriods.size(); -		mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + num_to_copy); +		mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + num_to_copy - 1);  	} -	if (getCurRecording().getDuration().value()) -	{ -		//call this to chain last period copied to new active period -		nextPeriod(); -	} +	// end with fresh period, otherwise next appendPeriodicRecording() will merge the first +	// recording period with the last one appended here +	nextPeriod();  	getCurRecording().setPlayState(getPlayState());  } diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index 5229fe69d7..2402cdbb95 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -117,7 +117,7 @@ struct LLUnit  	void operator *= (LLUnit<OTHER_STORAGE, OTHER_UNIT> multiplicand)  	{  		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template -		llstatic_assert_template(OTHER_UNIT, false, "Multiplication of unit types not supported."); +		LL_BAD_TEMPLATE_INSTANTIATION(OTHER_UNIT, "Multiplication of unit types not supported.");  	}  	void operator /= (storage_t divisor) @@ -129,7 +129,7 @@ struct LLUnit  	void operator /= (LLUnit<OTHER_STORAGE, OTHER_UNIT> divisor)  	{  		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template -		llstatic_assert_template(OTHER_UNIT, false, "Illegal in-place division of unit types."); +		LL_BAD_TEMPLATE_INSTANTIATION(OTHER_UNIT, "Illegal in-place division of unit types.");  	}  	template<typename SOURCE_STORAGE, typename SOURCE_UNITS> @@ -172,10 +172,11 @@ struct LLUnitImplicit : public LLUnit<STORAGE_TYPE, UNIT_TYPE>  template<typename S1, typename T1, typename S2, typename T2>  LL_FORCE_INLINE void ll_convert_units(LLUnit<S1, T1> in, LLUnit<S2, T2>& out, ...)  { -	static_assert(boost::is_same<T1, T2>::value  -					|| !boost::is_same<T1, typename T1::base_unit_t>::value  -					|| !boost::is_same<T2, typename T2::base_unit_t>::value,  -				"invalid conversion"); +	typedef boost::integral_constant<bool,  +									boost::is_same<T1, T2>::value  +										|| !boost::is_same<T1, typename T1::base_unit_t>::value  +										|| !boost::is_same<T2, typename T2::base_unit_t>::value> conversion_valid_t; +	LL_STATIC_ASSERT(conversion_valid_t::value, "invalid conversion");  	if (boost::is_same<T1, typename T1::base_unit_t>::value)  	{ @@ -322,7 +323,7 @@ template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, ty  LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator * (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)  {  	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template -	llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported."); +	LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "Multiplication of unit types results in new unit type - not supported.");  	return LLUnit<STORAGE_TYPE1, UNIT_TYPE1>();  } @@ -342,7 +343,7 @@ template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, ty  LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator * (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2>)  {  	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template -	llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported."); +	LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "Multiplication of unit types results in new unit type - not supported.");  	return LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>();  } diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 6f1e7d46b8..f188865eb0 100755 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -969,10 +969,7 @@ namespace tut                        childout.getline(), "ok");          // important to get the implicit flush from std::endl          py.mPy->getWritePipe().get_ostream() << "go" << std::endl; -        for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i) -        { -            yield(); -        } +        waitfor(*py.mPy);          ensure("script never replied", childout.contains("\n"));          ensure_equals("child didn't ack", childout.getline(), "ack");          ensure_equals("bad child termination", py.mPy->getStatus().mState, LLProcess::EXITED); | 
