diff options
| author | Merov Linden <merov@lindenlab.com> | 2014-06-17 09:50:48 -0700 | 
|---|---|---|
| committer | Merov Linden <merov@lindenlab.com> | 2014-06-17 09:50:48 -0700 | 
| commit | 9c792f03b4f006f5083c9fc98047bfad6bee8e16 (patch) | |
| tree | 5e15865f837e4d7815000b79452f4bdd7245d511 | |
| parent | f79b1139fd28b29c51a0c001960ef3f0bb999ec0 (diff) | |
| parent | 977476171ddcc057d7c28b6c14ae988b8189ed75 (diff) | |
Pull merge from lindenlab/viewer-release
80 files changed, 1089 insertions, 601 deletions
| @@ -481,3 +481,4 @@ fc066b82343fca51f9c1b8eda0abc6bee9bb4503 3.7.5-release  d029faf69f20a23007f32420a1ac6a3b89a6d441 3.7.6-release  83959480cb986522d07b151a0c778ab7f920d41b 3.7.7-release  bba9b3722eea08949e4ff69591f736bf0f808434 3.7.8-release +a9f2d0cb11f73b06858e6083bb50083becc3f9cd 3.7.9-release diff --git a/indra/llappearance/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp index 08084d3fe4..e630c1118b 100755 --- a/indra/llappearance/lldriverparam.cpp +++ b/indra/llappearance/lldriverparam.cpp @@ -152,19 +152,31 @@ void LLDriverParamInfo::toStream(std::ostream &out)  // LLDriverParam  //----------------------------------------------------------------------------- -LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) : +LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) +	: LLViewerVisualParam(), +	mDefaultVec(), +	mDriven(),  	mCurrentDistortionParam( NULL ),   	mAvatarAppearance(appearance),   	mWearablep(wearable)  {  	llassert(mAvatarAppearance); -	if (mWearablep) -	{ -		llassert(mAvatarAppearance->isSelf()); -	} +	llassert((mWearablep == NULL) || mAvatarAppearance->isSelf());  	mDefaultVec.clear();  } +LLDriverParam::LLDriverParam(const LLDriverParam& pOther) +	: LLViewerVisualParam(pOther), +	mDefaultVec(pOther.mDefaultVec), +	mDriven(pOther.mDriven), +	mCurrentDistortionParam(pOther.mCurrentDistortionParam), +	mAvatarAppearance(pOther.mAvatarAppearance), +	mWearablep(pOther.mWearablep) +{ +	llassert(mAvatarAppearance); +	llassert((mWearablep == NULL) || mAvatarAppearance->isSelf()); +} +  LLDriverParam::~LLDriverParam()  {  } @@ -186,13 +198,7 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)  /*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const  {  	llassert(wearable); -	LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable); -	// FIXME DRANO this clobbers mWearablep, which means any code -	// currently using mWearablep is wrong, or at least untested. -	*new_param = *this; -	//new_param->mWearablep = wearable; -//	new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables.  -	return new_param; +	return new LLDriverParam(*this);  }  void LLDriverParam::setWeight(F32 weight) diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h index 83301218dd..f71c930e5e 100755 --- a/indra/llappearance/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -129,6 +129,7 @@ public:  	const LLViewerVisualParam*		getDrivenParam(S32 index) const;  protected: +	LLDriverParam(const LLDriverParam& pOther);  	F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);  	void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight); diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 5224e3e3e1..e3992a080e 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -315,10 +315,27 @@ BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node)  // LLPolyMorphTarget()  //-----------------------------------------------------------------------------  LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh) -	: mMorphData(NULL), mMesh(poly_mesh), -	  mVertMask(NULL), -	  mLastSex(SEX_FEMALE), -	  mNumMorphMasksPending(0) +	: LLViewerVisualParam(), +	mMorphData(NULL), +	mMesh(poly_mesh), +	mVertMask(NULL), +	mLastSex(SEX_FEMALE), +	mNumMorphMasksPending(0), +	mVolumeMorphs() +{ +} + +//----------------------------------------------------------------------------- +// LLPolyMorphTarget() +//----------------------------------------------------------------------------- +LLPolyMorphTarget::LLPolyMorphTarget(const LLPolyMorphTarget& pOther) +	: LLViewerVisualParam(pOther), +	mMorphData(pOther.mMorphData), +	mMesh(pOther.mMesh), +	mVertMask(pOther.mVertMask == NULL ? NULL : new LLPolyVertexMask(*pOther.mVertMask)), +	mLastSex(pOther.mLastSex), +	mNumMorphMasksPending(pOther.mNumMorphMasksPending), +	mVolumeMorphs(pOther.mVolumeMorphs)  {  } @@ -327,10 +344,8 @@ LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh)  //-----------------------------------------------------------------------------  LLPolyMorphTarget::~LLPolyMorphTarget()  { -	if (mVertMask) -	{ -		delete mVertMask; -	} +	delete mVertMask; +	mVertMask = NULL;  }  //----------------------------------------------------------------------------- @@ -385,9 +400,7 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)  /*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const  { -	LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh); -	*new_param = *this; -	return new_param; +	return new LLPolyMorphTarget(*this);  }  #if 0 // obsolete @@ -722,10 +735,25 @@ void	LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3  // LLPolyVertexMask()  //-----------------------------------------------------------------------------  LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data) +	: mWeights(new F32[morph_data->mNumIndices]), +	mMorphData(morph_data), +	mWeightsGenerated(FALSE) +{ +	llassert(mMorphData != NULL); +	llassert(mMorphData->mNumIndices > 0); +} + +//----------------------------------------------------------------------------- +// LLPolyVertexMask() +//----------------------------------------------------------------------------- +LLPolyVertexMask::LLPolyVertexMask(const LLPolyVertexMask& pOther) +	: mWeights(new F32[pOther.mMorphData->mNumIndices]), +	mMorphData(pOther.mMorphData), +	mWeightsGenerated(pOther.mWeightsGenerated)  { -	mWeights = new F32[morph_data->mNumIndices]; -	mMorphData = morph_data; -	mWeightsGenerated = FALSE; +	llassert(mMorphData != NULL); +	llassert(mMorphData->mNumIndices > 0); +	memcpy(mWeights, pOther.mWeights, sizeof(F32) * mMorphData->mNumIndices);  }  //----------------------------------------------------------------------------- @@ -733,7 +761,8 @@ LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data)  //-----------------------------------------------------------------------------  LLPolyVertexMask::~LLPolyVertexMask()  { -	delete[] mWeights; +	delete [] mWeights; +	mWeights = NULL;  }  //----------------------------------------------------------------------------- diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h index ee380ae7c3..7e712f9e94 100644 --- a/indra/llappearance/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -91,6 +91,7 @@ class LLPolyVertexMask  {  public:  	LLPolyVertexMask(LLPolyMorphData* morph_data); +	LLPolyVertexMask(const LLPolyVertexMask& pOther);  	~LLPolyVertexMask();  	void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights); @@ -182,6 +183,8 @@ public:  	void	addPendingMorphMask() { mNumMorphMasksPending++; }  protected: +	LLPolyMorphTarget(const LLPolyMorphTarget& pOther); +  	LLPolyMorphData*				mMorphData;  	LLPolyMesh*						mMesh;  	LLPolyVertexMask *				mVertMask; diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index 4e2aa16762..ea29cbd451 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -104,9 +104,25 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)  // LLPolySkeletalDistortion()  //-----------------------------------------------------------------------------  LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp) +	: LLViewerVisualParam(), +	mDefaultVec(), +	mJointScales(), +	mJointOffsets(), +	mAvatar(avatarp) +{ +	mDefaultVec.splat(0.001f); +} + +//----------------------------------------------------------------------------- +// LLPolySkeletalDistortion() +//----------------------------------------------------------------------------- +LLPolySkeletalDistortion::LLPolySkeletalDistortion(const LLPolySkeletalDistortion &pOther) +	: LLViewerVisualParam(pOther), +	mDefaultVec(pOther.mDefaultVec), +	mJointScales(pOther.mJointScales), +	mJointOffsets(pOther.mJointOffsets), +	mAvatar(pOther.mAvatar)  { -        mAvatar = avatarp; -        mDefaultVec.splat(0.001f);  }  //----------------------------------------------------------------------------- @@ -171,9 +187,7 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)  /*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const  { -        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar); -        *new_param = *this; -        return new_param; +	return new LLPolySkeletalDistortion(*this);  }  //----------------------------------------------------------------------------- diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h index 24c9e9ae48..ea2adb8a87 100644 --- a/indra/llappearance/llpolyskeletaldistortion.h +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -118,6 +118,8 @@ public:  	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};  protected: +	LLPolySkeletalDistortion(const LLPolySkeletalDistortion& pOther); +  	LL_ALIGN_16(LLVector4a mDefaultVec);  	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;  	joint_vec_map_t mJointScales; diff --git a/indra/llappearance/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp index 633da4b851..3df2254b14 100755 --- a/indra/llappearance/lltexglobalcolor.cpp +++ b/indra/llappearance/lltexglobalcolor.cpp @@ -90,17 +90,31 @@ const std::string& LLTexGlobalColor::getName() const  //-----------------------------------------------------------------------------  // LLTexParamGlobalColor  //----------------------------------------------------------------------------- -LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) : -	LLTexLayerParamColor(tex_global_color->getAvatarAppearance()), +LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) +	: LLTexLayerParamColor(tex_global_color->getAvatarAppearance()),  	mTexGlobalColor(tex_global_color)  {  } +//----------------------------------------------------------------------------- +// LLTexParamGlobalColor +//----------------------------------------------------------------------------- +LLTexParamGlobalColor::LLTexParamGlobalColor(const LLTexParamGlobalColor& pOther) +	: LLTexLayerParamColor(pOther), +	mTexGlobalColor(pOther.mTexGlobalColor) +{ +} + +//----------------------------------------------------------------------------- +// ~LLTexParamGlobalColor +//----------------------------------------------------------------------------- +LLTexParamGlobalColor::~LLTexParamGlobalColor() +{ +} +  /*virtual*/ LLViewerVisualParam* LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const  { -	LLTexParamGlobalColor *new_param = new LLTexParamGlobalColor(mTexGlobalColor); -	*new_param = *this; -	return new_param; +	return new LLTexParamGlobalColor(*this);  }  void LLTexParamGlobalColor::onGlobalColorChanged() diff --git a/indra/llappearance/lltexglobalcolor.h b/indra/llappearance/lltexglobalcolor.h index 1b0c91b5ca..3b426053de 100755 --- a/indra/llappearance/lltexglobalcolor.h +++ b/indra/llappearance/lltexglobalcolor.h @@ -73,8 +73,10 @@ class LLTexParamGlobalColor : public LLTexLayerParamColor  {  public:  	LLTexParamGlobalColor(LLTexGlobalColor *tex_color); +	virtual ~LLTexParamGlobalColor();  	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;  protected: +	LLTexParamGlobalColor(const LLTexParamGlobalColor& pOther);  	/*virtual*/ void onGlobalColorChanged();  private:  	LLTexGlobalColor*		mTexGlobalColor; diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp index 4da5cf54e8..ff682d6906 100755 --- a/indra/llappearance/lltexlayerparams.cpp +++ b/indra/llappearance/lltexlayerparams.cpp @@ -40,7 +40,8 @@  //-----------------------------------------------------------------------------  // LLTexLayerParam  //----------------------------------------------------------------------------- -LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) : +LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) +	: LLViewerVisualParam(),  	mTexLayer(layer),  	mAvatarAppearance(NULL)  { @@ -54,12 +55,19 @@ LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :  	}  } -LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) : +LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) +	: LLViewerVisualParam(),  	mTexLayer(NULL),  	mAvatarAppearance(appearance)  {  } +LLTexLayerParam::LLTexLayerParam(const LLTexLayerParam& pOther) +	: LLViewerVisualParam(pOther), +	mTexLayer(pOther.mTexLayer), +	mAvatarAppearance(pOther.mAvatarAppearance) +{ +}  BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance)  { @@ -112,9 +120,11 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)  	}  } -LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) : -	LLTexLayerParam(layer), +LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) +	: LLTexLayerParam(layer),  	mCachedProcessedTexture(NULL), +	mStaticImageTGA(), +	mStaticImageRaw(),  	mNeedsCreateTexture(FALSE),  	mStaticImageInvalid(FALSE),  	mAvgDistortionVec(1.f, 1.f, 1.f), @@ -123,9 +133,11 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :  	sInstances.push_front(this);  } -LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) : -	LLTexLayerParam(appearance), +LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) +	: LLTexLayerParam(appearance),  	mCachedProcessedTexture(NULL), +	mStaticImageTGA(), +	mStaticImageRaw(),  	mNeedsCreateTexture(FALSE),  	mStaticImageInvalid(FALSE),  	mAvgDistortionVec(1.f, 1.f, 1.f), @@ -134,6 +146,18 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) :  	sInstances.push_front(this);  } +LLTexLayerParamAlpha::LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther) +	: LLTexLayerParam(pOther), +	mCachedProcessedTexture(pOther.mCachedProcessedTexture), +	mStaticImageTGA(pOther.mStaticImageTGA), +	mStaticImageRaw(pOther.mStaticImageRaw), +	mNeedsCreateTexture(pOther.mNeedsCreateTexture), +	mStaticImageInvalid(pOther.mStaticImageInvalid), +	mAvgDistortionVec(pOther.mAvgDistortionVec), +	mCachedEffectiveWeight(pOther.mCachedEffectiveWeight) +{ +	sInstances.push_front(this); +}  LLTexLayerParamAlpha::~LLTexLayerParamAlpha()  { @@ -143,9 +167,7 @@ LLTexLayerParamAlpha::~LLTexLayerParamAlpha()  /*virtual*/ LLViewerVisualParam* LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const  { -	LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer); -	*new_param = *this; -	return new_param; +	return new LLTexLayerParamAlpha(*this);  }  void LLTexLayerParamAlpha::deleteCaches() @@ -399,27 +421,31 @@ BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node) -LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) : -	LLTexLayerParam(layer), +LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) +	: LLTexLayerParam(layer),  	mAvgDistortionVec(1.f, 1.f, 1.f)  {  } -LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) : -	LLTexLayerParam(appearance), +LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) +	: LLTexLayerParam(appearance),  	mAvgDistortionVec(1.f, 1.f, 1.f)  {  } +LLTexLayerParamColor::LLTexLayerParamColor(const LLTexLayerParamColor& pOther) +	: LLTexLayerParam(pOther), +	mAvgDistortionVec(pOther.mAvgDistortionVec) +{ +} +  LLTexLayerParamColor::~LLTexLayerParamColor()  {  }  /*virtual*/ LLViewerVisualParam* LLTexLayerParamColor::cloneParam(LLWearable* wearable) const  { -	LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer); -	*new_param = *this; -	return new_param; +	return new LLTexLayerParamColor(*this);  }  LLColor4 LLTexLayerParamColor::getNetColor() const diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h index e1a8c28265..0cb2dedbff 100755 --- a/indra/llappearance/lltexlayerparams.h +++ b/indra/llappearance/lltexlayerparams.h @@ -52,6 +52,8 @@ public:  	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;  protected: +	LLTexLayerParam(const LLTexLayerParam& pOther); +  	LLTexLayerInterface*	mTexLayer;  	LLAvatarAppearance*		mAvatarAppearance;  }; @@ -102,6 +104,8 @@ public:  	BOOL					getMultiplyBlend() const;  private: +	LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther); +  	LLPointer<LLGLTexture>	mCachedProcessedTexture;  	LLPointer<LLImageTGA>	mStaticImageTGA;  	LLPointer<LLImageRaw>	mStaticImageRaw; @@ -190,6 +194,8 @@ public:  	// New functions  	LLColor4				getNetColor() const;  protected: +	LLTexLayerParamColor(const LLTexLayerParamColor& pOther); +  	virtual void onGlobalColorChanged() {}  private:  	LL_ALIGN_16(LLVector4a				mAvgDistortionVec); diff --git a/indra/llappearance/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp index 0d8d1dbeca..af8394b60c 100644 --- a/indra/llappearance/llviewervisualparam.cpp +++ b/indra/llappearance/llviewervisualparam.cpp @@ -123,6 +123,22 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)  // LLViewerVisualParam()  //-----------------------------------------------------------------------------  LLViewerVisualParam::LLViewerVisualParam() +	: LLVisualParam() +{ +} + +//----------------------------------------------------------------------------- +// LLViewerVisualParam() +//----------------------------------------------------------------------------- +LLViewerVisualParam::LLViewerVisualParam(const LLViewerVisualParam& pOther) +	: LLVisualParam(pOther) +{ +} + +//----------------------------------------------------------------------------- +// ~LLViewerVisualParam() +//----------------------------------------------------------------------------- +LLViewerVisualParam::~LLViewerVisualParam()  {  } diff --git a/indra/llappearance/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h index 2826e6c316..1a710c0ca6 100644 --- a/indra/llappearance/llviewervisualparam.h +++ b/indra/llappearance/llviewervisualparam.h @@ -70,7 +70,7 @@ class LLViewerVisualParam : public LLVisualParam  {  public:  	LLViewerVisualParam(); -	/*virtual*/ ~LLViewerVisualParam(){}; +	virtual ~LLViewerVisualParam();  	// Special: These functions are overridden by child classes  	LLViewerVisualParamInfo 	*getInfo() const { return (LLViewerVisualParamInfo*)mInfo; }; @@ -105,6 +105,8 @@ public:  	BOOL				getCrossWearable() const 	{ return getInfo()->mCrossWearable; } +protected: +	LLViewerVisualParam(const LLViewerVisualParam& pOther);  } LL_ALIGN_POSTFIX(16);  #endif // LL_LLViewerVisualParam_H diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index bacbc09aee..4bce3f99ed 100755 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -43,9 +43,32 @@ S32 LLWearable::sCurrentDefinitionVersion = 1;  // Private local functions  static std::string terse_F32_to_string(F32 f); +LLWearable::LLWearable() +	: mDefinitionVersion(-1), +	mName(), +	mDescription(), +	mPermissions(), +	mSaleInfo(), +	mType(LLWearableType::WT_NONE), +	mSavedVisualParamMap(), +	mVisualParamIndexMap(), +	mTEMap(), +	mSavedTEMap() +{ +} +  // virtual  LLWearable::~LLWearable()  { +	for (visual_param_index_map_t::iterator vpIter = mVisualParamIndexMap.begin(); vpIter != mVisualParamIndexMap.end(); ++vpIter) +	{ +		LLVisualParam* vp = vpIter->second; +		vp->clearNextParam(); +		delete vp; +		vpIter->second = NULL; +	} + +	destroyTextures();  }  const std::string& LLWearable::getTypeLabel() const @@ -620,17 +643,10 @@ void LLWearable::syncImages(te_map_t &src, te_map_t &dst)  void LLWearable::destroyTextures()  { -	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter ) -	{ -		LLLocalTextureObject *lto = iter->second; -		delete lto; -	} +	std::for_each(mTEMap.begin(), mTEMap.end(), DeletePairedPointer());  	mTEMap.clear(); -	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter ) -	{ -		LLLocalTextureObject *lto = iter->second; -		delete lto; -	} + +	std::for_each(mSavedTEMap.begin(), mSavedTEMap.end(), DeletePairedPointer());  	mSavedTEMap.clear();  } diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index 3e8bd2ca5d..406fc7e883 100755 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -46,6 +46,7 @@ class LLWearable  	// Constructors and destructors  	//--------------------------------------------------------------------  public: +	LLWearable();  	virtual ~LLWearable();  	//-------------------------------------------------------------------- diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 50ccfd75fb..e02b139608 100755 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -172,6 +172,13 @@ void LLMotionController::deleteAllMotions()  	for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());  	mAllMotions.clear(); + +	// stinson 05/12/20014 : Ownership of the LLMotion pointers is transferred from +	// mAllMotions to mDeprecatedMotions in method +	// LLMotionController::deprecateMotionInstance().  Thus, we should also clean +	// up the mDeprecatedMotions list as well. +	for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer()); +	mDeprecatedMotions.clear();  }  //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 17c003d07e..2235496ac5 100755 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -159,26 +159,42 @@ void LLVisualParamInfo::toStream(std::ostream &out)  //-----------------------------------------------------------------------------  // LLVisualParam()  //----------------------------------------------------------------------------- -LLVisualParam::LLVisualParam()	 -	: -	mCurWeight( 0.f ), +LLVisualParam::LLVisualParam() +	: mCurWeight( 0.f ),  	mLastWeight( 0.f ),  	mNext( NULL ),  	mTargetWeight( 0.f ),  	mIsAnimating( FALSE ), +	mIsDummy(FALSE),  	mID( -1 ),  	mInfo( 0 ), -	mIsDummy(FALSE),  	mParamLocation(LOC_UNKNOWN)  {  }  //----------------------------------------------------------------------------- +// LLVisualParam() +//----------------------------------------------------------------------------- +LLVisualParam::LLVisualParam(const LLVisualParam& pOther) +	: mCurWeight(pOther.mCurWeight), +	mLastWeight(pOther.mLastWeight), +	mNext(pOther.mNext), +	mTargetWeight(pOther.mTargetWeight), +	mIsAnimating(pOther.mIsAnimating), +	mIsDummy(pOther.mIsDummy), +	mID(pOther.mID), +	mInfo(pOther.mInfo), +	mParamLocation(pOther.mParamLocation) +{ +} + +//-----------------------------------------------------------------------------  // ~LLVisualParam()  //-----------------------------------------------------------------------------  LLVisualParam::~LLVisualParam()  {  	delete mNext; +	mNext = NULL;  }  /* @@ -285,6 +301,14 @@ void LLVisualParam::setNextParam( LLVisualParam *next )  }  //----------------------------------------------------------------------------- +// clearNextParam() +//----------------------------------------------------------------------------- +void LLVisualParam::clearNextParam() +{ +	mNext = NULL; +} + +//-----------------------------------------------------------------------------  // animate()  //-----------------------------------------------------------------------------  void LLVisualParam::animate( F32 delta) diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index 6c3bf2901a..c6b97d7e8b 100755 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -155,6 +155,7 @@ public:  	LLVisualParam*			getNextParam()		{ return mNext; }  	void					setNextParam( LLVisualParam *next ); +	void					clearNextParam();  	virtual void			setAnimating(BOOL is_animating) { mIsAnimating = is_animating && !mIsDummy; }  	BOOL					getAnimating() const { return mIsAnimating; } @@ -165,6 +166,8 @@ public:  	EParamLocation			getParamLocation() const { return mParamLocation; }  protected: +	LLVisualParam(const LLVisualParam& pOther); +  	F32					mCurWeight;			// current weight  	F32					mLastWeight;		// last weight  	LLVisualParam*		mNext;				// next param in a shared chain diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index a7963174ad..22cd861c72 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -47,6 +47,7 @@  #include "lllivefile.h"  #include "llsd.h"  #include "llsdserialize.h" +#include "llsingleton.h"  #include "llstl.h"  #include "lltimer.h" @@ -356,30 +357,31 @@ namespace  	typedef std::map<std::string, LLError::ELevel> LevelMap; -	typedef std::vector<LLError::Recorder*> Recorders; +	typedef std::vector<LLError::RecorderPtr> Recorders;  	typedef std::vector<LLError::CallSite*> CallSiteVector; -	class Globals +	class Globals : public LLSingleton<Globals>  	{  	public: +		Globals(); +  		std::ostringstream messageStream;  		bool messageStreamInUse;  		void addCallSite(LLError::CallSite&);  		void invalidateCallSites(); -		 -		static Globals& get(); -			// return the one instance of the globals  	private:  		CallSiteVector callSites; - -		Globals() -			:	messageStreamInUse(false) -			{ } -		  	}; +	Globals::Globals() +		: messageStream(), +		messageStreamInUse(false), +		callSites() +	{ +	} +  	void Globals::addCallSite(LLError::CallSite& site)  	{  		callSites.push_back(&site); @@ -396,25 +398,17 @@ namespace  		callSites.clear();  	} - -	Globals& Globals::get() -	{ -		/* This pattern, of returning a reference to a static function -		   variable, is to ensure that this global is constructed before -		   it is used, no matter what the global initialization sequence -		   is. -		   See C++ FAQ Lite, sections 10.12 through 10.14 -		*/ -		static Globals* globals = new Globals;		 -		return *globals; -	}  }  namespace LLError  { -	class Settings +	class SettingsConfig : public LLRefCount  	{ +		friend class Settings; +  	public: +		virtual ~SettingsConfig(); +  		bool                                mPrintLocation;  		LLError::ELevel                     mDefaultLevel; @@ -429,81 +423,86 @@ namespace LLError  		LLError::TimeFunction               mTimeFunction;  		Recorders                           mRecorders; -		Recorder*                           mFileRecorder; -		Recorder*                           mFixedBufferRecorder; +		RecorderPtr                         mFileRecorder; +		RecorderPtr                         mFixedBufferRecorder;  		std::string                         mFileRecorderFileName;  		int									mShouldLogCallCounter; -		static Settings& get(); +	private: +		SettingsConfig(); +	}; + +	typedef LLPointer<SettingsConfig> SettingsConfigPtr; + +	class Settings : public LLSingleton<Settings> +	{ +	public: +		Settings(); + +		SettingsConfigPtr getSettingsConfig(); -		static void reset(); -		static Settings* saveAndReset(); -		static void restore(Settings*); +		void reset(); +		SettingsStoragePtr saveAndReset(); +		void restore(SettingsStoragePtr pSettingsStorage);  	private: -		Settings() -		:	mPrintLocation(false), -			mDefaultLevel(LLError::LEVEL_DEBUG), -			mCrashFunction(), -			mTimeFunction(NULL), -			mFileRecorder(NULL), -			mFixedBufferRecorder(NULL), -			mShouldLogCallCounter(0) -			{ } -		 -		~Settings() -		{ -			for_each(mRecorders.begin(), mRecorders.end(), DeletePointer()); -			mRecorders.clear(); -		} -		 -		static Settings*& getPtr(); +		SettingsConfigPtr mSettingsConfig;  	}; -	Settings& Settings::get() +	SettingsConfig::SettingsConfig() +		: LLRefCount(), +		mPrintLocation(false), +		mDefaultLevel(LLError::LEVEL_DEBUG), +		mFunctionLevelMap(), +		mClassLevelMap(), +		mFileLevelMap(), +		mTagLevelMap(), +		mUniqueLogMessages(), +		mCrashFunction(NULL), +		mTimeFunction(NULL), +		mRecorders(), +		mFileRecorder(), +		mFixedBufferRecorder(), +		mFileRecorderFileName(), +		mShouldLogCallCounter(0)  	{ -		Settings* p = getPtr(); -		if (!p) -		{ -			reset(); -			p = getPtr(); -		} -		return *p;  	} -	 -	void Settings::reset() + +	SettingsConfig::~SettingsConfig()  	{ -		Globals::get().invalidateCallSites(); -		 -		Settings*& p = getPtr(); -		delete p; -		p = new Settings(); +		mRecorders.clear(); +	} + +	Settings::Settings() +		: LLSingleton<Settings>(), +		mSettingsConfig(new SettingsConfig()) +	{ +	} + +	SettingsConfigPtr Settings::getSettingsConfig() +	{ +		return mSettingsConfig;  	} -	Settings* Settings::saveAndReset() +	void Settings::reset()  	{ -		Globals::get().invalidateCallSites(); -		 -		Settings*& p = getPtr(); -		Settings* originalSettings = p; -		p = new Settings(); -		return originalSettings; +		Globals::getInstance()->invalidateCallSites(); +		mSettingsConfig = new SettingsConfig();  	} -	void Settings::restore(Settings* originalSettings) +	SettingsStoragePtr Settings::saveAndReset()  	{ -		Globals::get().invalidateCallSites(); -		 -		Settings*& p = getPtr(); -		delete p; -		p = originalSettings; +		SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get()); +		reset(); +		return oldSettingsConfig;  	} -	Settings*& Settings::getPtr() +	void Settings::restore(SettingsStoragePtr pSettingsStorage)  	{ -		static Settings* currentSettings = NULL; -		return currentSettings; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get())); +		mSettingsConfig = newSettingsConfig;  	}  } @@ -604,7 +603,7 @@ namespace  	void commonInit(const std::string& dir, bool log_to_stderr = true)  	{ -		LLError::Settings::reset(); +		LLError::Settings::getInstance()->reset();  		LLError::setDefaultLevel(LLError::LEVEL_INFO);  		LLError::setFatalFunction(LLError::crashAndLoop); @@ -613,11 +612,13 @@ namespace  		// log_to_stderr is only false in the unit and integration tests to keep builds quieter  		if (log_to_stderr && shouldLogToStderr())  		{ -			LLError::addRecorder(new RecordToStderr(stderrLogWantsTime())); +			LLError::RecorderPtr recordToStdErr(new RecordToStderr(stderrLogWantsTime())); +			LLError::addRecorder(recordToStdErr);  		}  #if LL_WINDOWS -		LLError::addRecorder(new RecordToWinDebug); +		LLError::RecorderPtr recordToWinDebug(new RecordToWinDebug()); +		LLError::addRecorder(recordToWinDebug);  #endif  		LogControlFile& e = LogControlFile::fromDirectory(dir); @@ -645,7 +646,8 @@ namespace LLError  		}  		commonInit(dir);  #if !LL_WINDOWS -		addRecorder(new RecordToSyslog(identity)); +		LLError::RecorderPtr recordToSyslog(new RecordToSyslog(identity)); +		addRecorder(recordToSyslog);  #endif  	} @@ -656,72 +658,67 @@ namespace LLError  	void setPrintLocation(bool print)  	{ -		Settings& s = Settings::get(); -		s.mPrintLocation = print; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mPrintLocation = print;  	}  	void setFatalFunction(const FatalFunction& f)  	{ -		Settings& s = Settings::get(); -		s.mCrashFunction = f; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mCrashFunction = f;  	}      FatalFunction getFatalFunction()      { -        Settings& s = Settings::get(); -        return s.mCrashFunction; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +        return s->mCrashFunction;      }  	void setTimeFunction(TimeFunction f)  	{ -		Settings& s = Settings::get(); -		s.mTimeFunction = f; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mTimeFunction = f;  	}  	void setDefaultLevel(ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mDefaultLevel = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mDefaultLevel = level;  	}  	ELevel getDefaultLevel()  	{ -		Settings& s = Settings::get(); -		return s.mDefaultLevel; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		return s->mDefaultLevel;  	}  	void setFunctionLevel(const std::string& function_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mFunctionLevelMap[function_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mFunctionLevelMap[function_name] = level;  	}  	void setClassLevel(const std::string& class_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mClassLevelMap[class_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mClassLevelMap[class_name] = level;  	}  	void setFileLevel(const std::string& file_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mFileLevelMap[file_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mFileLevelMap[file_name] = level;  	}  	void setTagLevel(const std::string& tag_name, ELevel level)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); -		g.invalidateCallSites(); -		s.mTagLevelMap[tag_name] = level; +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mTagLevelMap[tag_name] = level;  	}  	LLError::ELevel decodeLevel(std::string name) @@ -765,15 +762,14 @@ namespace LLError  {  	void configure(const LLSD& config)  	{ -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); +		Globals::getInstance()->invalidateCallSites(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		g.invalidateCallSites(); -		s.mFunctionLevelMap.clear(); -		s.mClassLevelMap.clear(); -		s.mFileLevelMap.clear(); -		s.mTagLevelMap.clear(); -		s.mUniqueLogMessages.clear(); +		s->mFunctionLevelMap.clear(); +		s->mClassLevelMap.clear(); +		s->mFileLevelMap.clear(); +		s->mTagLevelMap.clear(); +		s->mUniqueLogMessages.clear();  		setPrintLocation(config["print-location"]);  		setDefaultLevel(decodeLevel(config["default-level"])); @@ -786,10 +782,10 @@ namespace LLError  			ELevel level = decodeLevel(entry["level"]); -			setLevels(s.mFunctionLevelMap,	entry["functions"],	level); -			setLevels(s.mClassLevelMap,		entry["classes"],	level); -			setLevels(s.mFileLevelMap,		entry["files"],		level); -			setLevels(s.mTagLevelMap,		entry["tags"],		level); +			setLevels(s->mFunctionLevelMap,	entry["functions"],	level); +			setLevels(s->mClassLevelMap,	entry["classes"],	level); +			setLevels(s->mFileLevelMap,		entry["files"],		level); +			setLevels(s->mTagLevelMap,		entry["tags"],		level);  		}  	}  } @@ -803,10 +799,12 @@ namespace LLError  		mWantsLevel(true),  		mWantsLocation(false),  		mWantsFunctionName(true) -	{} +	{ +	}  	Recorder::~Recorder() -		{ } +	{ +	}  	bool Recorder::wantsTime()  	{  @@ -837,25 +835,25 @@ namespace LLError  		return mWantsFunctionName;  	} -	void addRecorder(Recorder* recorder) +	void addRecorder(RecorderPtr recorder)  	{ -		if (recorder == NULL) +		if (!recorder)  		{  			return;  		} -		Settings& s = Settings::get(); -		s.mRecorders.push_back(recorder); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mRecorders.push_back(recorder);  	} -	void removeRecorder(Recorder* recorder) +	void removeRecorder(RecorderPtr recorder)  	{ -		if (recorder == NULL) +		if (!recorder)  		{  			return;  		} -		Settings& s = Settings::get(); -		s.mRecorders.erase(std::remove(s.mRecorders.begin(), s.mRecorders.end(), recorder), -							s.mRecorders.end()); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		s->mRecorders.erase(std::remove(s->mRecorders.begin(), s->mRecorders.end(), recorder), +							s->mRecorders.end());  	}  } @@ -863,51 +861,47 @@ namespace LLError  {  	void logToFile(const std::string& file_name)  	{ -		LLError::Settings& s = LLError::Settings::get(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		removeRecorder(s.mFileRecorder); -		delete s.mFileRecorder; -		s.mFileRecorder = NULL; -		s.mFileRecorderFileName.clear(); +		removeRecorder(s->mFileRecorder); +		s->mFileRecorder.reset(); +		s->mFileRecorderFileName.clear();  		if (file_name.empty())  		{  			return;  		} -		RecordToFile* f = new RecordToFile(file_name); -		if (!f->okay()) +		RecorderPtr recordToFile(new RecordToFile(file_name)); +		if (boost::dynamic_pointer_cast<RecordToFile>(recordToFile)->okay())  		{ -			delete f; -			return; +			s->mFileRecorderFileName = file_name; +			s->mFileRecorder = recordToFile; +			addRecorder(recordToFile);  		} - -		s.mFileRecorderFileName = file_name; -		s.mFileRecorder = f; -		addRecorder(f);  	}  	void logToFixedBuffer(LLLineBuffer* fixedBuffer)  	{ -		LLError::Settings& s = LLError::Settings::get(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		removeRecorder(s.mFixedBufferRecorder); -		delete s.mFixedBufferRecorder; -		s.mFixedBufferRecorder = NULL; +		removeRecorder(s->mFixedBufferRecorder); +		s->mFixedBufferRecorder.reset();  		if (!fixedBuffer)  		{  			return;  		} -		s.mFixedBufferRecorder = new RecordToFixedBuffer(fixedBuffer); -		addRecorder(s.mFixedBufferRecorder); +		RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer)); +		s->mFixedBufferRecorder = recordToFixedBuffer; +		addRecorder(recordToFixedBuffer);  	}  	std::string logFileName()  	{ -		LLError::Settings& s = LLError::Settings::get(); -		return s.mFileRecorderFileName; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		return s->mFileRecorderFileName;  	}  } @@ -916,24 +910,24 @@ namespace  	void writeToRecorders(const LLError::CallSite& site, const std::string& message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true)  	{  		LLError::ELevel level = site.mLevel; -		LLError::Settings& s = LLError::Settings::get(); +		LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig(); -		for (Recorders::const_iterator i = s.mRecorders.begin(); -			i != s.mRecorders.end(); +		for (Recorders::const_iterator i = s->mRecorders.begin(); +			i != s->mRecorders.end();  			++i)  		{ -			LLError::Recorder* r = *i; +			LLError::RecorderPtr r = *i;  			std::ostringstream message_stream; -			if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s.mPrintLocation)) +			if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation))  			{  				message_stream << site.mLocationString << " ";  			} -			if (show_time && r->wantsTime() && s.mTimeFunction != NULL) +			if (show_time && r->wantsTime() && s->mTimeFunction != NULL)  			{ -				message_stream << s.mTimeFunction() << " "; +				message_stream << s->mTimeFunction() << " ";  			}  			if (show_level && r->wantsLevel()) @@ -1060,10 +1054,9 @@ namespace LLError  			return false;  		} -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		s.mShouldLogCallCounter++; +		s->mShouldLogCallCounter++;  		const std::string& class_name = className(site.mClassInfo);  		std::string function_name = functionName(site.mFunction); @@ -1077,21 +1070,21 @@ namespace LLError  			function_name = class_name + "::" + function_name;  		} -		ELevel compareLevel = s.mDefaultLevel; +		ELevel compareLevel = s->mDefaultLevel;  		// The most specific match found will be used as the log level,  		// since the computation short circuits.  		// So, in increasing order of importance:  		// Default < Tags < File < Class < Function -		checkLevelMap(s.mFunctionLevelMap, function_name, compareLevel) -		|| checkLevelMap(s.mClassLevelMap, class_name, compareLevel) -		|| checkLevelMap(s.mFileLevelMap, abbreviateFile(site.mFile), compareLevel) +		checkLevelMap(s->mFunctionLevelMap, function_name, compareLevel) +		|| checkLevelMap(s->mClassLevelMap, class_name, compareLevel) +		|| checkLevelMap(s->mFileLevelMap, abbreviateFile(site.mFile), compareLevel)  		|| (site.mTagCount > 0 -			? checkLevelMap(s.mTagLevelMap, site.mTags, site.mTagCount, compareLevel)  +			? checkLevelMap(s->mTagLevelMap, site.mTags, site.mTagCount, compareLevel)   			: false);  		site.mCached = true; -		g.addCallSite(site); +		Globals::getInstance()->addCallSite(site);  		return site.mShouldLog = site.mLevel >= compareLevel;  	} @@ -1101,12 +1094,12 @@ namespace LLError  		LogLock lock;  		if (lock.ok())  		{ -			Globals& g = Globals::get(); +			Globals* g = Globals::getInstance(); -			if (!g.messageStreamInUse) +			if (!g->messageStreamInUse)  			{ -				g.messageStreamInUse = true; -				return &g.messageStream; +				g->messageStreamInUse = true; +				return &g->messageStream;  			}  		} @@ -1131,13 +1124,12 @@ namespace LLError  		   message[127] = '\0' ;  	   } -	   Globals& g = Globals::get(); - -       if (out == &g.messageStream) +	   Globals* g = Globals::getInstance(); +       if (out == &g->messageStream)         { -           g.messageStream.clear(); -           g.messageStream.str(""); -           g.messageStreamInUse = false; +           g->messageStream.clear(); +           g->messageStream.str(""); +           g->messageStreamInUse = false;         }         else         { @@ -1154,15 +1146,15 @@ namespace LLError  			return;  		} -		Globals& g = Globals::get(); -		Settings& s = Settings::get(); +		Globals* g = Globals::getInstance(); +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();  		std::string message = out->str(); -		if (out == &g.messageStream) +		if (out == &g->messageStream)  		{ -			g.messageStream.clear(); -			g.messageStream.str(""); -			g.messageStreamInUse = false; +			g->messageStream.clear(); +			g->messageStream.str(""); +			g->messageStreamInUse = false;  		}  		else  		{ @@ -1178,8 +1170,8 @@ namespace LLError  		if (site.mPrintOnce)  		{ -			std::map<std::string, unsigned int>::iterator messageIter = s.mUniqueLogMessages.find(message); -			if (messageIter != s.mUniqueLogMessages.end()) +			std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message); +			if (messageIter != s->mUniqueLogMessages.end())  			{  				messageIter->second++;  				unsigned int num_messages = messageIter->second; @@ -1195,7 +1187,7 @@ namespace LLError  			else   			{  				message_stream << "ONCE: "; -				s.mUniqueLogMessages[message] = 1; +				s->mUniqueLogMessages[message] = 1;  			}  		} @@ -1203,23 +1195,23 @@ namespace LLError  		writeToRecorders(site, message_stream.str()); -		if (site.mLevel == LEVEL_ERROR  &&  s.mCrashFunction) +		if (site.mLevel == LEVEL_ERROR  &&  s->mCrashFunction)  		{ -			s.mCrashFunction(message_stream.str()); +			s->mCrashFunction(message_stream.str());  		}  	}  }  namespace LLError  { -	Settings* saveAndResetSettings() +	SettingsStoragePtr saveAndResetSettings()  	{ -		return Settings::saveAndReset(); +		return Settings::getInstance()->saveAndReset();  	} -	void restoreSettings(Settings* s) +	void restoreSettings(SettingsStoragePtr pSettingsStorage)  	{ -		return Settings::restore(s); +		return Settings::getInstance()->restore(pSettingsStorage);  	}  	std::string removePrefix(std::string& s, const std::string& p) @@ -1265,8 +1257,8 @@ namespace LLError  	int shouldLogCallCount()  	{ -		Settings& s = Settings::get(); -		return s.mShouldLogCallCounter; +		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); +		return s->mShouldLogCallCounter;  	}  #if LL_WINDOWS @@ -1375,15 +1367,9 @@ namespace LLError  #endif  	//static -   void LLCallStacks::push(const char* function, const int line) +   void LLCallStacks::allocateStackBuffer()     { -	   CallStacksLogLock lock; -       if (!lock.ok()) -       { -           return; -       } - -	   if(!sBuffer) +	   if(sBuffer == NULL)  	   {  		   sBuffer = new char*[512] ;  		   sBuffer[0] = new char[512 * 128] ; @@ -1393,6 +1379,31 @@ namespace LLError  		   }  		   sIndex = 0 ;  	   } +   } + +   void LLCallStacks::freeStackBuffer() +   { +	   if(sBuffer != NULL) +	   { +		   delete [] sBuffer[0] ; +		   delete [] sBuffer ; +		   sBuffer = NULL ; +	   } +   } + +   //static +   void LLCallStacks::push(const char* function, const int line) +   { +	   CallStacksLogLock lock; +       if (!lock.ok()) +       { +           return; +       } + +	   if(sBuffer == NULL) +	   { +		   allocateStackBuffer(); +	   }  	   if(sIndex > 511)  	   { @@ -1424,15 +1435,9 @@ namespace LLError             return;         } -	   if(!sBuffer) +	   if(sBuffer == NULL)  	   { -		   sBuffer = new char*[512] ; -		   sBuffer[0] = new char[512 * 128] ; -		   for(S32 i = 1 ; i < 512 ; i++) -		   { -			   sBuffer[i] = sBuffer[i-1] + 128 ; -		   } -		   sIndex = 0 ; +		   allocateStackBuffer();  	   }  	   if(sIndex > 511) @@ -1463,11 +1468,9 @@ namespace LLError             LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;         } -	   if(sBuffer) +	   if(sBuffer != NULL)  	   { -		   delete[] sBuffer[0] ; -		   delete[] sBuffer ; -		   sBuffer = NULL ; +		   freeStackBuffer();  	   }     } @@ -1477,5 +1480,10 @@ namespace LLError         sIndex = 0 ;     } +   //static +   void LLCallStacks::cleanup() +   { +	   freeStackBuffer(); +   }  } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index bc80e64423..63040e1772 100755 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -261,6 +261,9 @@ namespace LLError     private:         static char**  sBuffer ;  	   static S32     sIndex ; + +	   static void allocateStackBuffer(); +	   static void freeStackBuffer();     public:     	   static void push(const char* function, const int line) ; @@ -268,6 +271,7 @@ namespace LLError         static void print() ;         static void clear() ;  	   static void end(std::ostringstream* _out) ; +	   static void cleanup();     };   } diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index aab695094c..56ac52e5de 100755 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -29,7 +29,10 @@  #define LL_LLERRORCONTROL_H  #include "llerror.h" +#include "llpointer.h" +#include "llrefcount.h"  #include "boost/function.hpp" +#include "boost/shared_ptr.hpp"  #include <string>  class LLSD; @@ -156,16 +159,14 @@ namespace LLError  				mWantsFunctionName;  	}; +	typedef boost::shared_ptr<Recorder> RecorderPtr; +  	/** -	 * @NOTE: addRecorder() conveys ownership to the underlying Settings -	 * object -- when destroyed, it will @em delete the passed Recorder*! -	 */ -	LL_COMMON_API void addRecorder(Recorder*); -	/** -	 * @NOTE: removeRecorder() reclaims ownership of the Recorder*: its -	 * lifespan becomes the caller's problem. +	 * @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership +	 * while still ensuring that the allocated memory is eventually freed  	 */ -	LL_COMMON_API void removeRecorder(Recorder*); +	LL_COMMON_API void addRecorder(RecorderPtr); +	LL_COMMON_API void removeRecorder(RecorderPtr);  		// each error message is passed to each recorder via recordMessage()  	LL_COMMON_API void logToFile(const std::string& filename); @@ -182,9 +183,9 @@ namespace LLError  		Utilities for use by the unit tests of LLError itself.  	*/ -	class Settings; -	LL_COMMON_API Settings* saveAndResetSettings(); -	LL_COMMON_API void restoreSettings(Settings *); +	typedef LLPointer<LLRefCount> SettingsStoragePtr; +	LL_COMMON_API SettingsStoragePtr saveAndResetSettings(); +	LL_COMMON_API void restoreSettings(SettingsStoragePtr pSettingsStorage);  	LL_COMMON_API std::string abbreviateFile(const std::string& filePath);  	LL_COMMON_API int shouldLogCallCount(); diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 2532566319..7aa87fcd0e 100755 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -31,6 +31,7 @@  #include <vector>  #include <list>  #include <boost/function.hpp> +#include <boost/shared_ptr.hpp>  #include <boost/type_traits/is_convertible.hpp>  #include <boost/type_traits/is_enum.hpp>  #include <boost/unordered_map.hpp> @@ -629,7 +630,7 @@ namespace LLInitParam  		UserData*			mUserData;  	}; -	typedef ParamDescriptor* ParamDescriptorPtr; +	typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;  	// each derived Block class keeps a static data structure maintaining offsets to various params  	class LL_COMMON_API BlockDescriptor diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index b28c5ba4b3..a5aaff10c5 100755 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -56,9 +56,9 @@ namespace tut  	{  	public:  		TestRecorder() { mWantsTime = false; } -		~TestRecorder() { LLError::removeRecorder(this); } +		virtual ~TestRecorder() {  } -		void recordMessage(LLError::ELevel level, +		virtual void recordMessage(LLError::ELevel level,  						   const std::string& message)  		{  			mMessages.push_back(message); @@ -85,15 +85,11 @@ namespace tut  	struct ErrorTestData  	{ -		// addRecorder() expects to be able to later delete the passed -		// Recorder*. Even though removeRecorder() reclaims ownership, passing -		// a pointer to a data member rather than a heap Recorder subclass -		// instance would just be Wrong. -		TestRecorder* mRecorder; -		LLError::Settings* mPriorErrorSettings; +		LLError::RecorderPtr mRecorder; +		LLError::SettingsStoragePtr mPriorErrorSettings;  		ErrorTestData(): -			mRecorder(new TestRecorder) +			mRecorder(new TestRecorder())  		{  			fatalWasCalled = false; @@ -106,13 +102,32 @@ namespace tut  		~ErrorTestData()  		{  			LLError::removeRecorder(mRecorder); -			delete mRecorder;  			LLError::restoreSettings(mPriorErrorSettings);  		} +		int countMessages() +		{ +			return boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->countMessages(); +		} + +		void clearMessages() +		{ +			boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->clearMessages(); +		} + +		void setWantsTime(bool t) +		{ +			boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->setWantsTime(t); +		} + +		std::string message(int n) +		{ +			return boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->message(n); +		} +  		void ensure_message_count(int expectedCount)  		{ -			ensure_equals("message count", mRecorder->countMessages(), expectedCount); +			ensure_equals("message count", countMessages(), expectedCount);  		}  		void ensure_message_contains(int n, const std::string& expectedText) @@ -120,7 +135,7 @@ namespace tut  			std::ostringstream test_name;  			test_name << "testing message " << n; -			ensure_contains(test_name.str(), mRecorder->message(n), expectedText); +			ensure_contains(test_name.str(), message(n), expectedText);  		}  		void ensure_message_does_not_contain(int n, const std::string& expectedText) @@ -128,7 +143,7 @@ namespace tut  			std::ostringstream test_name;  			test_name << "testing message " << n; -			ensure_does_not_contain(test_name.str(), mRecorder->message(n), expectedText); +			ensure_does_not_contain(test_name.str(), message(n), expectedText);  		}  	}; @@ -385,15 +400,15 @@ namespace  	}  	typedef std::string (*LogFromFunction)(bool); -	void testLogName(tut::TestRecorder* recorder, LogFromFunction f, +	void testLogName(LLError::RecorderPtr recorder, LogFromFunction f,  		const std::string& class_name = "")  	{ -		recorder->clearMessages(); +		boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->clearMessages();  		std::string name = f(false);  		f(true); -		std::string messageWithoutName = recorder->message(0); -		std::string messageWithName = recorder->message(1); +		std::string messageWithoutName = boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->message(0); +		std::string messageWithName = boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->message(1);  		ensure_has(name + " logged without name",  			messageWithoutName, name); @@ -528,12 +543,12 @@ namespace tut  	{  		LLError::setTimeFunction(roswell); -		mRecorder->setWantsTime(false); +		setWantsTime(false);  		ufoSighting();  		ensure_message_contains(0, "ufo");  		ensure_message_does_not_contain(0, roswell()); -		mRecorder->setWantsTime(true); +		setWantsTime(true);  		ufoSighting();  		ensure_message_contains(1, "ufo");  		ensure_message_contains(1, roswell()); @@ -545,13 +560,13 @@ namespace tut  	{  		LLError::setPrintLocation(true);  		LLError::setTimeFunction(roswell); -		mRecorder->setWantsTime(true); +		setWantsTime(true);  		std::string location,  					function;  		writeReturningLocationAndFunction(location, function);  		ensure_equals("order is location time type function message", -			mRecorder->message(0), +			message(0),  			location + roswell() + " INFO: " + function + ": apple");  	} @@ -559,19 +574,19 @@ namespace tut  		// multiple recorders  	void ErrorTestObject::test<11>()  	{ -		TestRecorder* altRecorder(new TestRecorder); +		LLError::RecorderPtr altRecorder(new TestRecorder());  		LLError::addRecorder(altRecorder);  		LL_INFOS() << "boo" << LL_ENDL;  		ensure_message_contains(0, "boo"); -		ensure_equals("alt recorder count", altRecorder->countMessages(), 1); -		ensure_contains("alt recorder message 0", altRecorder->message(0), "boo"); +		ensure_equals("alt recorder count", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->countMessages(), 1); +		ensure_contains("alt recorder message 0", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->message(0), "boo");  		LLError::setTimeFunction(roswell); -		TestRecorder* anotherRecorder(new TestRecorder); -		anotherRecorder->setWantsTime(true); +		LLError::RecorderPtr anotherRecorder(new TestRecorder()); +		boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->setWantsTime(true);  		LLError::addRecorder(anotherRecorder);  		LL_INFOS() << "baz" << LL_ENDL; @@ -579,10 +594,13 @@ namespace tut  		std::string when = roswell();  		ensure_message_does_not_contain(1, when); -		ensure_equals("alt recorder count", altRecorder->countMessages(), 2); -		ensure_does_not_contain("alt recorder message 1", altRecorder->message(1), when); -		ensure_equals("another recorder count", anotherRecorder->countMessages(), 1); -		ensure_contains("another recorder message 0", anotherRecorder->message(0), when); +		ensure_equals("alt recorder count", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->countMessages(), 2); +		ensure_does_not_contain("alt recorder message 1", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->message(1), when); +		ensure_equals("another recorder count", boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->countMessages(), 1); +		ensure_contains("another recorder message 0", boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->message(0), when); + +		LLError::removeRecorder(altRecorder); +		LLError::removeRecorder(anotherRecorder);  	}  } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 3137bd8fea..785197ba11 100755 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -38,6 +38,7 @@  #include "stringize.h"  #include <boost/bind.hpp>  #include <boost/noncopyable.hpp> +#include <boost/shared_ptr.hpp>  #include <list>  #include <string>  #include <stdexcept> @@ -81,72 +82,29 @@ struct WrapLLErrs      }      std::string error; -    LLError::Settings* mPriorErrorSettings; +    LLError::SettingsStoragePtr mPriorErrorSettings;      LLError::FatalFunction mPriorFatal;  };  /** - * LLError::addRecorder() accepts ownership of the passed Recorder* -- it - * expects to be able to delete it later. CaptureLog isa Recorder whose - * pointer we want to be able to pass without any ownership implications. - * For such cases, instantiate a new RecorderProxy(yourRecorder) and pass - * that. Your heap RecorderProxy might later be deleted, but not yourRecorder. - */ -class RecorderProxy: public LLError::Recorder -{ -public: -    RecorderProxy(LLError::Recorder* recorder): -        mRecorder(recorder) -    {} - -    virtual void recordMessage(LLError::ELevel level, const std::string& message) -    { -        mRecorder->recordMessage(level, message); -    } - -    virtual bool wantsTime() -    { -        return mRecorder->wantsTime(); -    } - -private: -    LLError::Recorder* mRecorder; -}; - -/**   * Capture log messages. This is adapted (simplified) from the one in   * llerror_test.cpp.   */ -class CaptureLog : public LLError::Recorder, public boost::noncopyable +class CaptureLogRecorder : public LLError::Recorder, public boost::noncopyable  {  public: -    CaptureLog(LLError::ELevel level=LLError::LEVEL_DEBUG): -        // Mostly what we're trying to accomplish by saving and resetting -        // LLError::Settings is to bypass the default RecordToStderr and -        // RecordToWinDebug Recorders. As these are visible only inside -        // llerror.cpp, we can't just call LLError::removeRecorder() with -        // each. For certain tests we need to produce, capture and examine -        // DEBUG log messages -- but we don't want to spam the user's console -        // with that output. If it turns out that saveAndResetSettings() has -        // some bad effect, give up and just let the DEBUG level log messages -        // display. -        mOldSettings(LLError::saveAndResetSettings()), -        mProxy(new RecorderProxy(this)) +    CaptureLogRecorder() +		: LLError::Recorder(), +		boost::noncopyable(), +		mMessages()      { -        LLError::setFatalFunction(wouldHaveCrashed); -        LLError::setDefaultLevel(level); -        LLError::addRecorder(mProxy);      } -    ~CaptureLog() +    virtual ~CaptureLogRecorder()      { -        LLError::removeRecorder(mProxy); -        delete mProxy; -        LLError::restoreSettings(mOldSettings);      } -    void recordMessage(LLError::ELevel level, -                       const std::string& message) +    virtual void recordMessage(LLError::ELevel level, const std::string& message)      {          mMessages.push_back(message);      } @@ -154,7 +112,7 @@ public:      /// Don't assume the message we want is necessarily the LAST log message      /// emitted by the underlying code; search backwards through all messages      /// for the sought string. -    std::string messageWith(const std::string& search, bool required=true) +    std::string messageWith(const std::string& search, bool required)      {          for (MessageList::const_reverse_iterator rmi(mMessages.rbegin()), rmend(mMessages.rend());               rmi != rmend; ++rmi) @@ -187,14 +145,63 @@ public:          return out;      } +private:      typedef std::list<std::string> MessageList;      MessageList mMessages; -    LLError::Settings* mOldSettings; -    LLError::Recorder* mProxy; +}; + +/** + * Capture log messages. This is adapted (simplified) from the one in + * llerror_test.cpp. + */ +class CaptureLog : public boost::noncopyable +{ +public: +    CaptureLog(LLError::ELevel level=LLError::LEVEL_DEBUG) +        // Mostly what we're trying to accomplish by saving and resetting +        // LLError::Settings is to bypass the default RecordToStderr and +        // RecordToWinDebug Recorders. As these are visible only inside +        // llerror.cpp, we can't just call LLError::removeRecorder() with +        // each. For certain tests we need to produce, capture and examine +        // DEBUG log messages -- but we don't want to spam the user's console +        // with that output. If it turns out that saveAndResetSettings() has +        // some bad effect, give up and just let the DEBUG level log messages +        // display. +		: boost::noncopyable(), +        mOldSettings(LLError::saveAndResetSettings()), +		mRecorder(new CaptureLogRecorder()) +    { +        LLError::setFatalFunction(wouldHaveCrashed); +        LLError::setDefaultLevel(level); +        LLError::addRecorder(mRecorder); +    } + +    ~CaptureLog() +    { +        LLError::removeRecorder(mRecorder); +        LLError::restoreSettings(mOldSettings); +    } + +    /// Don't assume the message we want is necessarily the LAST log message +    /// emitted by the underlying code; search backwards through all messages +    /// for the sought string. +    std::string messageWith(const std::string& search, bool required=true) +    { +		return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required); +    } + +    std::ostream& streamto(std::ostream& out) const +    { +		return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out); +    } + +private: +    LLError::SettingsStoragePtr mOldSettings; +	LLError::RecorderPtr mRecorder;  };  inline -std::ostream& operator<<(std::ostream& out, const CaptureLog& log) +std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)  {      return log.streamto(out);  } diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp index 81e28121fd..9f90ae1544 100755 --- a/indra/llmessage/llares.cpp +++ b/indra/llmessage/llares.cpp @@ -610,6 +610,15 @@ LLAres *ll_init_ares()  	return gAres;  } +void ll_cleanup_ares() +{ +	if (gAres != NULL) +	{ +		delete gAres; +		gAres = NULL; +	} +} +  LLDnsRecord::LLDnsRecord(LLResType type, const std::string &name,  						 unsigned ttl)  	: LLRefCount(), diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h index 800781ee88..0b5d49e322 100755 --- a/indra/llmessage/llares.h +++ b/indra/llmessage/llares.h @@ -578,5 +578,6 @@ extern LLAres *gAres;   * thread safe.   */  extern LLAres *ll_init_ares(); +extern void ll_cleanup_ares();  #endif // LL_LLARES_H diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index a80d5a570e..73df47b933 100755 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -349,6 +349,36 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle)  	}  } +//static +void LLCurl::Easy::deleteAllActiveHandles() +{ +	LLMutexLock lock(sHandleMutexp) ; +	LL_CHECK_MEMORY +	for (std::set<CURL*>::iterator activeHandle = sActiveHandles.begin(); activeHandle != sActiveHandles.end(); ++activeHandle) +	{ +		CURL* curlHandle = *activeHandle; +		LLCurl::deleteEasyHandle(curlHandle); +		LL_CHECK_MEMORY +	} + +	sFreeHandles.clear(); +} + +//static +void LLCurl::Easy::deleteAllFreeHandles() +{ +	LLMutexLock lock(sHandleMutexp) ; +	LL_CHECK_MEMORY +	for (std::set<CURL*>::iterator freeHandle = sFreeHandles.begin(); freeHandle != sFreeHandles.end(); ++freeHandle) +	{ +		CURL* curlHandle = *freeHandle; +		LLCurl::deleteEasyHandle(curlHandle); +		LL_CHECK_MEMORY +	} + +	sFreeHandles.clear(); +} +  LLCurl::Easy::Easy()  	: mHeaders(NULL),  	  mCurlEasyHandle(NULL) @@ -1857,17 +1887,14 @@ void LLCurl::cleanupClass()  #endif  	LL_CHECK_MEMORY - -	for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter) -	{ -		CURL* curl = *iter; -		LLCurl::deleteEasyHandle(curl); -	} -	 +	Easy::deleteAllFreeHandles(); +	LL_CHECK_MEMORY +	Easy::deleteAllActiveHandles();  	LL_CHECK_MEMORY -	Easy::sFreeHandles.clear(); - +	// Free the template easy handle +	curl_easy_cleanup(sCurlTemplateStandardHandle); +	sCurlTemplateStandardHandle = NULL;  	LL_CHECK_MEMORY  	delete Easy::sHandleMutexp ; diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index bd6b0b3fd4..385d9fffa8 100755 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -304,6 +304,9 @@ private:  	static std::set<CURL*> sFreeHandles;  	static std::set<CURL*> sActiveHandles;  	static LLMutex*        sHandleMutexp ; + +	static void deleteAllActiveHandles(); +	static void deleteAllFreeHandles();  };  class LLCurl::Multi diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 801cf83fae..a8c3b86192 100755 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -127,7 +127,7 @@ namespace  	{  	public:  		RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {} -		virtual ~RawInjector() {delete mData;} +		virtual ~RawInjector() {delete [] mData;}  		const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; } diff --git a/indra/llplugin/llplugincookiestore.cpp b/indra/llplugin/llplugincookiestore.cpp index f64b264222..a5d717389d 100755 --- a/indra/llplugin/llplugincookiestore.cpp +++ b/indra/llplugin/llplugincookiestore.cpp @@ -27,6 +27,7 @@   */  #include "linden_common.h" +#include "llstl.h"  #include "indra_constants.h"  #include "llplugincookiestore.h" @@ -654,12 +655,8 @@ void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_t  void LLPluginCookieStore::clearCookies()  { -	while(!mCookies.empty()) -	{ -		cookie_map_t::iterator iter = mCookies.begin(); -		delete iter->second; -		mCookies.erase(iter); -	} +	std::for_each(mCookies.begin(), mCookies.end(), DeletePairedPointer()); +	mCookies.clear();  }  void LLPluginCookieStore::removeCookie(const std::string &key) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index ea0d2b81f1..b5a2588e1e 100755 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -131,6 +131,8 @@ LLPluginProcessParent::~LLPluginProcessParent()  	{  		// destroy the shared memory region  		iter->second->destroy(); +		delete iter->second; +		iter->second = NULL;  		// and remove it from our map  		mSharedMemoryRegions.erase(iter); @@ -960,6 +962,8 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)  			{  				// destroy the shared memory region  				iter->second->destroy(); +				delete iter->second; +				iter->second = NULL;  				// and remove it from our map  				mSharedMemoryRegions.erase(iter); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ddf38c6745..ebed454271 100755 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -390,9 +390,7 @@ LLImageGL::~LLImageGL()  {  	LLImageGL::cleanup();  	sImageList.erase(this); -	disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8); -	delete [] mPickMask; -	mPickMask = NULL; +	freePickMask();  	sCount--;  } @@ -461,6 +459,8 @@ void LLImageGL::cleanup()  	{  		destroyGLTexture();  	} +	freePickMask(); +  	mSaveData = NULL; // deletes data  } @@ -504,10 +504,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve  		}  		// pickmask validity depends on old image size, delete it -		disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8); -		delete [] mPickMask; -		mPickMask = NULL; -		mPickMaskWidth = mPickMaskHeight = 0; +		freePickMask();  		mWidth = width;  		mHeight = height; @@ -1886,6 +1883,37 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)  }  //---------------------------------------------------------------------------- +U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight) +{ +	U32 pick_width = pWidth/2 + 1; +	U32 pick_height = pHeight/2 + 1; + +	U32 size = pick_width * pick_height; +	size = (size + 7) / 8; // pixelcount-to-bits +	mPickMask = new U8[size]; +	claimMem(size); +	mPickMaskWidth = pick_width - 1; +	mPickMaskHeight = pick_height - 1; + +	memset(mPickMask, 0, sizeof(U8) * size); + +	return size; +} + +//---------------------------------------------------------------------------- +void LLImageGL::freePickMask() +{ +	// pickmask validity depends on old image size, delete it +	if (mPickMask != NULL) +	{ +		disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8); +		delete [] mPickMask; +	} +	mPickMask = NULL; +	mPickMaskWidth = mPickMaskHeight = 0; +} + +//----------------------------------------------------------------------------  void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)  {  	if(!mNeedsAlphaAndPickMask) @@ -1893,10 +1921,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)  		return ;  	} -	disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8); -	delete [] mPickMask; -	mPickMask = NULL; -	mPickMaskWidth = mPickMaskHeight = 0; +	freePickMask();  	if (mFormatType != GL_UNSIGNED_BYTE ||  	    mFormatPrimary != GL_RGBA) @@ -1905,17 +1930,11 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)  		return;  	} -	U32 pick_width = width/2 + 1; -	U32 pick_height = height/2 + 1; - -	U32 size = pick_width * pick_height; -	size = (size + 7) / 8; // pixelcount-to-bits -	mPickMask = new U8[size]; -	claimMem(size); -	mPickMaskWidth = pick_width - 1; -	mPickMaskHeight = pick_height - 1; - -	memset(mPickMask, 0, sizeof(U8) * size); +#ifdef SHOW_ASSERT +	const U32 pickSize = createPickMask(width, height); +#else // SHOW_ASSERT +	createPickMask(width, height); +#endif // SHOW_ASSERT  	U32 pick_bit = 0; @@ -1929,7 +1948,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)  			{  				U32 pick_idx = pick_bit/8;  				U32 pick_offset = pick_bit%8; -				llassert(pick_idx < size); +				llassert(pick_idx < pickSize);  				mPickMask[pick_idx] |= 1 << pick_offset;  			} diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 6ca814af6f..21982eab1d 100755 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -186,6 +186,9 @@ public:  	mutable F32  mLastBindTime;	// last time this was bound, by discard level  private: +	U32 createPickMask(S32 pWidth, S32 pHeight); +	void freePickMask(); +  	LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL  	U8* mPickMask;  //downsampled bitmap approximation of alpha channel.  NULL if no alpha channel  	U16 mPickMaskWidth; diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp index 1860a05edd..55e64bb940 100755 --- a/indra/llui/llbadgeowner.cpp +++ b/indra/llui/llbadgeowner.cpp @@ -35,8 +35,9 @@  //  LLBadgeOwner::LLBadgeOwner(LLHandle< LLView > viewHandle) -	: mBadge(NULL) -	, mBadgeOwnerView(viewHandle) +	: mHasBadgeHolderParent(false), +	mBadge(NULL), +	mBadgeOwnerView(viewHandle)  {  } @@ -45,31 +46,12 @@ void LLBadgeOwner::initBadgeParams(const LLBadge::Params& p)  	if (!p.equals(LLUICtrlFactory::getDefaultParams<LLBadge>()))  	{  		mBadge = createBadge(p); -	} -} - -void LLBadgeOwner::setBadgeLabel(const LLStringExplicit& label) -{ -	if (mBadge == NULL) -	{ -		mBadge = createBadge(LLUICtrlFactory::getDefaultParams<LLBadge>()); - -		addBadgeToParentPanel(); -	} - -	if (mBadge) -	{ -		mBadge->setLabel(label); - -		// -		// Push the badge to the front so it renders on top -		// - -		LLView * parent = mBadge->getParent(); +		mHasBadgeHolderParent = false; -		if (parent) +		LLView * owner_view = mBadgeOwnerView.get(); +		if (owner_view)  		{ -			parent->sendChildToFront(mBadge); +			mBadge->addToView(owner_view);  		}  	}  } @@ -82,10 +64,8 @@ void LLBadgeOwner::setBadgeVisibility(bool visible)  	}  } -bool LLBadgeOwner::addBadgeToParentPanel() +void LLBadgeOwner::addBadgeToParentHolder()  { -	bool badge_added = false; -  	LLView * owner_view = mBadgeOwnerView.get();  	if (mBadge && owner_view) @@ -110,16 +90,9 @@ bool LLBadgeOwner::addBadgeToParentPanel()  		if (badge_holder)  		{ -			badge_added = badge_holder->addBadge(mBadge); -		} -		else -		{ -			// Badge parent is fallback badge owner if no valid holder exists in the hierarchy -			badge_added = mBadge->addToView(owner_view); +			mHasBadgeHolderParent = badge_holder->addBadge(mBadge);  		}  	} - -	return badge_added;  }  LLBadge* LLBadgeOwner::createBadge(const LLBadge::Params& p) diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h index 8d03e30645..53c2de95c8 100755 --- a/indra/llui/llbadgeowner.h +++ b/indra/llui/llbadgeowner.h @@ -41,11 +41,9 @@ public:  	LLBadgeOwner(LLHandle< LLView > viewHandle);  	void initBadgeParams(const LLBadge::Params& p); -	bool addBadgeToParentPanel(); +	void addBadgeToParentHolder(); -	bool badgeHasParent() const { return (mBadge && mBadge->getParent()); } - -	void setBadgeLabel(const LLStringExplicit& label); +	bool hasBadgeHolderParent() const { return mHasBadgeHolderParent; };  	void setBadgeVisibility(bool visible);  private: @@ -53,7 +51,7 @@ private:  	LLBadge* createBadge(const LLBadge::Params& p);  private: - +	bool				mHasBadgeHolderParent;  	LLBadge*			mBadge;  	LLHandle< LLView >	mBadgeOwnerView;  }; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 093d91d44d..ce8383857c 100755 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -384,7 +384,7 @@ BOOL LLButton::postBuild()  {  	autoResize(); -	addBadgeToParentPanel(); +	addBadgeToParentHolder();  	return LLUICtrl::postBuild();  } diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 2fb57d55e7..692f3965f1 100755 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -227,10 +227,11 @@ LLFolderView::LLFolderView(const Params& p)  	mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);  	mStatusTextBox->setFollowsLeft();  	mStatusTextBox->setFollowsTop(); -	//addChild(mStatusTextBox); +	addChild(mStatusTextBox);  	// make the popup menu available +	llassert(LLMenuGL::sMenuContainer != NULL);  	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());  	if (!menu)  	{ diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index d410a2de33..b09c927782 100755 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -192,6 +192,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)  	setPrevalidateInput(p.prevalidate_input_callback());  	setPrevalidate(p.prevalidate_callback()); +	llassert(LLMenuGL::sMenuContainer != NULL);  	LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>  		("menu_text_editor.xml",  		 LLMenuGL::sMenuContainer, diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index 0609cd8b42..303afcda15 100755 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -93,6 +93,7 @@ void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition posit  		return;  	} +	llassert(LLMenuGL::sMenuContainer != NULL);  	LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());  	if (!menu)  	{ diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 7383a8c307..604dc92789 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -63,6 +63,7 @@  // static  LLMenuHolderGL *LLMenuGL::sMenuContainer = NULL; +view_listener_t::listener_map_t view_listener_t::sListeners;  S32 MENU_BAR_HEIGHT = 0;  S32 MENU_BAR_WIDTH = 0; diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index feafaab199..ae9b169691 100755 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -895,7 +895,8 @@ class view_listener_t : public boost::signals2::trackable  {  public:  	virtual bool handleEvent(const LLSD& userdata) = 0; -	virtual ~view_listener_t() {} +	view_listener_t() { sListeners.insert(this); } +	virtual ~view_listener_t() { sListeners.erase(this); }  	static void addEnable(view_listener_t* listener, const std::string& name)  	{ @@ -913,6 +914,20 @@ public:  		addEnable(listener, name);  		addCommit(listener, name);  	} + +	static void cleanup() +	{ +		listener_vector_t listeners(sListeners.begin(), sListeners.end()); +		sListeners.clear(); + +		std::for_each(listeners.begin(), listeners.end(), DeletePointer()); +		listeners.clear(); +	} + +private: +	typedef std::set<view_listener_t*> listener_map_t; +	typedef std::vector<view_listener_t*> listener_vector_t; +	static listener_map_t sListeners;  };  #endif // LL_LLMENUGL_H diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 3708071e11..5f72ee3ac6 100755 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1815,6 +1815,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)  			// create the context menu from the XUI file and display it  			std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";  			delete mPopupMenu; +			llassert(LLMenuGL::sMenuContainer != NULL);  			mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(  				menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());  			if (mPopupMenu) diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index ebc6183b8b..6f858cdeb3 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1140,6 +1140,17 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)  			addChild( btn, 0 );  		}  	} +	else +	{ +		if (textbox) +		{ +			LLUICtrl::addChild(textbox, 0); +		} +		if (btn) +		{ +			LLUICtrl::addChild(btn, 0); +		} +	}  	if (child)  	{ @@ -1636,16 +1647,26 @@ void LLTabContainer::setTabImage(LLPanel* child, LLIconCtrl* icon)  {  	LLTabTuple* tuple = getTabByPanel(child);  	LLCustomButtonIconCtrl* button; +	bool hasButton = false;  	if(tuple)  	{  		button = dynamic_cast<LLCustomButtonIconCtrl*>(tuple->mButton);  		if(button)  		{ +			hasButton = true;  			button->setIcon(icon);  			reshapeTuple(tuple);  		}  	} + +	if (!hasButton && (icon != NULL)) +	{ +		// It was assumed that the tab's button would take ownership of the icon pointer. +		// But since the tab did not have a button, kill the icon to prevent the memory +		// leak. +		icon->die(); +	}  }  void LLTabContainer::reshapeTuple(LLTabTuple* tuple) diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 62edbadb07..8906a6e736 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1955,6 +1955,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)  	// create and return the context menu from the XUI file  	delete mPopupMenu; +	llassert(LLMenuGL::sMenuContainer != NULL);  	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,  																		 LLMenuHolderGL::child_registry_t::instance());	  	if (mIsFriendSignal) @@ -2037,7 +2038,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para  		LLUrlMatch match;  		std::string text = new_text;  		while ( LLUrlRegistry::instance().findUrl(text, match, -				boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) +				boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))  		{  			start = match.getStart();  			end = match.getEnd()+1; @@ -2074,7 +2075,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para  					}  			} -			LLTextUtil::processUrlMatch(&match,this); +			LLTextUtil::processUrlMatch(&match,this,isContentTrusted());  			// move on to the rest of the text after the Url  			if (end < (S32)text.length())  diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index d1f66b6cfe..ecbfdaf84c 100755 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -367,7 +367,9 @@ public:  	bool					getWordWrap() { return mWordWrap; }  	bool					getUseEllipses() { return mUseEllipses; }  	bool					truncate(); // returns true of truncation occurred +  	bool					isContentTrusted() {return mTrustedContent;} +	void					setContentTrusted(bool trusted_content) { mTrustedContent = trusted_content; }  	// TODO: move into LLTextSegment?  	void					createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index c797b6acc5..b4ebed0849 100755 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2031,6 +2031,7 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)  {  	if (!mContextMenu)  	{ +		llassert(LLMenuGL::sMenuContainer != NULL);  		mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml",   																				LLMenuGL::sMenuContainer,   																				LLMenuHolderGL::child_registry_t::instance()); diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp index 4df2c3363f..fff04b34f2 100755 --- a/indra/llui/lltextutil.cpp +++ b/indra/llui/lltextutil.cpp @@ -72,7 +72,7 @@ const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)  	return formatted_phone_str;  } -bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base) +bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted)  {  	if (match == 0 || text_base == 0)  		return false; @@ -85,7 +85,7 @@ bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base)  	}  	// output an optional icon before the Url -	if (!match->getIcon().empty() ) +	if (is_content_trusted && !match->getIcon().empty() )  	{  		LLUIImagePtr image = LLUI::getUIImage(match->getIcon());  		if (image) diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h index bf7dbb58ce..798f14d086 100755 --- a/indra/llui/lltextutil.h +++ b/indra/llui/lltextutil.h @@ -64,7 +64,7 @@ namespace LLTextUtil  	 */  	const std::string& formatPhoneNumber(const std::string& phone_str); -	bool processUrlMatch(LLUrlMatch* match,LLTextBase* text_base); +	bool processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted);  	class TextHelpers  	{ diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index f9bdd87087..abc2b6e9ca 100755 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -148,6 +148,7 @@ void LLToolBar::createContextMenu()  		enable_reg.add("Toolbars.CheckSetting", boost::bind(&LLToolBar::isSettingChecked, this, _2));  		// Create the context menu +		llassert(LLMenuGL::sMenuContainer != NULL);  		LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_toolbars.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());  		if (menu) diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 523ee5d78c..bccc646821 100755 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -41,7 +41,8 @@ LLUrlRegistry::LLUrlRegistry()  	// Urls are matched in the order that they were registered  	registerUrl(new LLUrlEntryNoLink()); -	registerUrl(new LLUrlEntryIcon()); +	mUrlEntryIcon = new LLUrlEntryIcon(); +	registerUrl(mUrlEntryIcon);  	registerUrl(new LLUrlEntrySLURL());  	registerUrl(new LLUrlEntryHTTP());  	registerUrl(new LLUrlEntryHTTPLabel()); @@ -145,7 +146,7 @@ static bool stringHasUrl(const std::string &text)  			text.find("<icon") != std::string::npos);  } -bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb) +bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted)  {  	// avoid costly regexes if there is clearly no URL in the text  	if (! stringHasUrl(text)) @@ -160,6 +161,12 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL  	std::vector<LLUrlEntryBase *>::iterator it;  	for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it)  	{ +		//Skip for url entry icon if content is not trusted +		if(!is_content_trusted && (mUrlEntryIcon == *it)) +		{ +			continue; +		} +  		LLUrlEntryBase *url_entry = *it;  		U32 start = 0, end = 0; diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index da16171a97..6270df1bbb 100755 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -73,7 +73,8 @@ public:  	/// get the next Url in an input string, starting at a given character offset  	/// your callback is invoked if the matched Url's label changes in the future  	bool findUrl(const std::string &text, LLUrlMatch &match, -				 const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback); +				 const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback, +				 bool is_content_trusted = false);  	/// a slightly less efficient version of findUrl for wide strings  	bool findUrl(const LLWString &text, LLUrlMatch &match, @@ -92,6 +93,7 @@ private:  	friend class LLSingleton<LLUrlRegistry>;  	std::vector<LLUrlEntryBase *> mUrlEntry; +	LLUrlEntryBase*	mUrlEntryIcon;  };  #endif diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 0637572f67..19961d5759 100755 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -657,7 +657,7 @@ LLWindowWin32::~LLWindowWin32()  	delete [] mSupportedResolutions;  	mSupportedResolutions = NULL; -	delete mWindowClassName; +	delete [] mWindowClassName;  	mWindowClassName = NULL;  } diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index c77a7de85c..f06fb9e915 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.9 +3.7.10 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f98ec69732..f52e6625c1 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2019,6 +2019,9 @@ bool LLAppViewer::cleanup()  	// Non-LLCurl libcurl library  	mAppCoreHttp.cleanup(); +	// NOTE The following call is not thread safe.  +	ll_cleanup_ares(); +  	LLFilePickerThread::cleanupClass();  	//MUST happen AFTER LLCurl::cleanupClass @@ -2114,6 +2117,8 @@ bool LLAppViewer::cleanup()  	ll_close_fail_log(); +	LLError::LLCallStacks::cleanup(); +  	removeMarkerFiles();      LL_INFOS() << "Goodbye!" << LL_ENDL; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 06f081e920..57fb84bbf1 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -438,7 +438,7 @@ void LLAppViewerWin32::disableWinErrorReporting()  const S32 MAX_CONSOLE_LINES = 500; -void create_console() +static bool create_console()  {  	int h_con_handle;  	long l_std_handle; @@ -447,7 +447,7 @@ void create_console()  	FILE *fp;  	// allocate a console for this app -	AllocConsole(); +	const bool isConsoleAllocated = AllocConsole();  	// set the screen buffer to be big enough to let us scroll text  	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); @@ -495,10 +495,13 @@ void create_console()  		*stderr = *fp;  		setvbuf( stderr, NULL, _IONBF, 0 );  	} + +    return isConsoleAllocated;  }  LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) : -    mCmdLine(cmd_line) +	mCmdLine(cmd_line), +	mIsConsoleAllocated(false)  {  } @@ -542,6 +545,16 @@ bool LLAppViewerWin32::cleanup()  	gDXHardware.cleanup(); +#ifndef LL_RELEASE_FOR_DOWNLOAD +	LLWinDebug::instance().cleanup(); +#endif + +	if (mIsConsoleAllocated) +	{ +		FreeConsole(); +		mIsConsoleAllocated = false; +	} +  	return result;  } @@ -553,7 +566,7 @@ void LLAppViewerWin32::initLoggingAndGetLastDuration()  void LLAppViewerWin32::initConsole()  {  	// pop up debug console -	create_console(); +	mIsConsoleAllocated = create_console();  	return LLAppViewer::initConsole();  } diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index fb37df1a2f..59d1ddaa3d 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -61,7 +61,8 @@ protected:  private:  	void disableWinErrorReporting(); -    std::string mCmdLine; +	std::string mCmdLine; +	bool mIsConsoleAllocated;  };  #endif // LL_LLAPPVIEWERWIN32_H diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 05c4181714..84b9ac756a 100755 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -107,6 +107,7 @@ class LLChatHistoryHeader: public LLPanel  public:  	LLChatHistoryHeader()  	:	LLPanel(), +		mInfoCtrl(NULL),  		mPopupMenuHandleAvatar(),  		mPopupMenuHandleObject(),  		mAvatarID(), @@ -129,9 +130,6 @@ public:  	~LLChatHistoryHeader()  	{ -		// Detach the info button so that it doesn't get destroyed (EXT-8463). -		hideInfoCtrl(); -  		if (mAvatarNameCacheConnection.connected())  		{  			mAvatarNameCacheConnection.disconnect(); @@ -292,6 +290,11 @@ public:  		mUserNameTextBox = getChild<LLTextBox>("user_name");  		mTimeBoxTextBox = getChild<LLTextBox>("time_box"); +		mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance()); +		llassert(mInfoCtrl != NULL); +		mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl)); +		mInfoCtrl->setVisible(FALSE); +  		return LLPanel::postBuild();  	} @@ -589,39 +592,19 @@ protected:  	void showInfoCtrl()  	{ -		if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return; -				 -		if (!sInfoCtrl) -		{ -			// *TODO: Delete the button at exit. -			sInfoCtrl = LLUICtrlFactory::createFromFile<LLUICtrl>("inspector_info_ctrl.xml", NULL, LLPanel::child_registry_t::instance()); -			if (sInfoCtrl) -			{ -				sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl)); -			} -		} - -		if (!sInfoCtrl) +		const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType; +		if (isVisible)  		{ -			llassert(sInfoCtrl != NULL); -			return; +			const LLRect sticky_rect = mUserNameTextBox->getRect(); +			S32 icon_x = llmin(sticky_rect.mLeft + mUserNameTextBox->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3); +			mInfoCtrl->setOrigin(icon_x, sticky_rect.getCenterY() - mInfoCtrl->getRect().getHeight() / 2 ) ;  		} - -		LLTextBox* name = getChild<LLTextBox>("user_name"); -		LLRect sticky_rect = name->getRect(); -		S32 icon_x = llmin(sticky_rect.mLeft + name->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3); -		sInfoCtrl->setOrigin(icon_x, sticky_rect.getCenterY() - sInfoCtrl->getRect().getHeight() / 2 ) ; -		addChild(sInfoCtrl); +		mInfoCtrl->setVisible(isVisible);  	}  	void hideInfoCtrl()  	{ -		if (!sInfoCtrl) return; - -		if (sInfoCtrl->getParent() == this) -		{ -			removeChild(sInfoCtrl); -		} +		mInfoCtrl->setVisible(FALSE);  	}  private: @@ -692,7 +675,7 @@ protected:  	LLHandle<LLView>	mPopupMenuHandleAvatar;  	LLHandle<LLView>	mPopupMenuHandleObject; -	static LLUICtrl*	sInfoCtrl; +	LLUICtrl*			mInfoCtrl;  	LLUUID			    mAvatarID;  	LLSD				mObjectData; @@ -709,8 +692,6 @@ private:  	boost::signals2::connection mAvatarNameCacheConnection;  }; -LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL; -  LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)  :	LLUICtrl(p),  	mMessageHeaderFilename(p.message_header), diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index bb6d4fb59c..44736a0489 100755 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -93,14 +93,15 @@ class LLChatHistory : public LLUICtrl  		 * @return pointer to LLView separator object.  		 */  		LLView* getSeparator(); + +		void onClickMoreText(); + +	private:  		/**  		 * Builds a message header.  		 * @return pointer to LLView header object.  		 */  		LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args); - -		void onClickMoreText(); -  	public:  		~LLChatHistory();  		LLSD getValue() const;    diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index fd4f17b694..cfc62c07b6 100755 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -29,7 +29,6 @@  #include "llchatitemscontainerctrl.h"  #include "lltextbox.h" -#include "llchatmsgbox.h"  #include "llavatariconctrl.h"  #include "llcommandhandler.h"  #include "llfloaterreg.h" @@ -130,7 +129,6 @@ void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)  {  	std::string		messageText = notification["message"].asString();		// UTF-8 line of text -	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);  	std::string color_name = notification["text_color"].asString(); @@ -171,7 +169,7 @@ void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)  		{  			style_params.font.style = "ITALIC";  		} -		msg_text->appendText(messageText, TRUE, style_params); +		mMsgText->appendText(messageText, TRUE, style_params);  	}  	snapToMessageHeight(); @@ -204,9 +202,10 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)  		case 2:	messageFont = LLFontGL::getFontSansSerifBig();	break;  	} -	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false); +	mMsgText = getChild<LLChatMsgBox>("msg_text", false); +	mMsgText->setContentTrusted(false); -	msg_text->setText(std::string("")); +	mMsgText->setText(std::string(""));  	if ( notification["chat_style"].asInteger() != CHAT_STYLE_IRC )  	{ @@ -232,12 +231,12 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)  			style_params_name.link_href = notification["sender_slurl"].asString();  			style_params_name.is_link = true; -			msg_text->appendText(str_sender, FALSE, style_params_name); +			mMsgText->appendText(str_sender, FALSE, style_params_name);  		}  		else  		{ -			msg_text->appendText(str_sender, false); +			mMsgText->appendText(str_sender, false);  		}  	} @@ -264,7 +263,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)  		{  			style_params.font.style = "ITALIC";  		} -		msg_text->appendText(messageText, FALSE, style_params); +		mMsgText->appendText(messageText, FALSE, style_params);  	} @@ -275,8 +274,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)  void	LLFloaterIMNearbyChatToastPanel::snapToMessageHeight	()  { -	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); -	S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25); +	S32 new_height = llmax (mMsgText->getTextPixelHeight() + 2*mMsgText->getVPad() + 2*msg_height_pad, 25);  	LLRect panel_rect = getRect(); @@ -312,14 +310,13 @@ BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)  		return LLPanel::handleMouseUp(x,y,mask);      */ -	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); -	S32 local_x = x - text_box->getRect().mLeft; -	S32 local_y = y - text_box->getRect().mBottom; +	S32 local_x = x - mMsgText->getRect().mLeft; +	S32 local_y = y - mMsgText->getRect().mBottom;  	//if text_box process mouse up (ussually this is click on url) - we didn't show nearby_chat. -	if (text_box->pointInView(local_x, local_y) ) +	if (mMsgText->pointInView(local_x, local_y) )  	{ -		if (text_box->handleMouseUp(local_x,local_y,mask) == TRUE) +		if (mMsgText->handleMouseUp(local_x,local_y,mask) == TRUE)  			return TRUE;  		else  		{ diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h index 54b6499d52..f66670ec8c 100755 --- a/indra/newview/llchatitemscontainerctrl.h +++ b/indra/newview/llchatitemscontainerctrl.h @@ -28,6 +28,7 @@  #define LL_LLCHATITEMSCONTAINERCTRL_H_  #include "llchat.h" +#include "llchatmsgbox.h"  #include "llpanel.h"  #include "llscrollbar.h"  #include "llviewerchat.h" @@ -85,6 +86,7 @@ private:  	LLUUID			mFromID;	// agent id or object id  	std::string		mFromName;  	EChatSourceType	mSourceType; +	LLChatMsgBox* 	mMsgText; diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index b1dce42dfd..c0823182c0 100755 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -204,6 +204,7 @@ void LLNotificationChiclet::createMenu()  	enable_registrar.add("NotificationWellChicletMenu.EnableItem",  		boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2)); +	llassert(LLMenuGL::sMenuContainer != NULL);  	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>  		("menu_notification_well_button.xml",  		 LLMenuGL::sMenuContainer, diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp index a624c9fb87..6bda8b1d0d 100755 --- a/indra/newview/lllistcontextmenu.cpp +++ b/indra/newview/lllistcontextmenu.cpp @@ -110,6 +110,7 @@ void LLListContextMenu::handleMultiple(functor_t functor, const uuid_vec_t& ids)  // static  LLContextMenu* LLListContextMenu::createFromFile(const std::string& filename)  { +	llassert(LLMenuGL::sMenuContainer != NULL);  	return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(  		filename, LLContextMenu::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());  } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index f406bb9f06..0178512cb5 100755 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -391,8 +391,12 @@ BOOL LLMediaCtrl::postBuild ()  	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;  	registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); +	// stinson 05/05/2014 : use this as the parent of the context menu if the static menu +	// container has yet to be created +	LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this); +	llassert(menuParent != NULL);  	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( -		"menu_media_ctrl.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); +		"menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance());  	setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2));  	return TRUE; @@ -1118,3 +1122,8 @@ void LLMediaCtrl::setTrustedContent(bool trusted)  		mMediaSource->setTrustedBrowser(trusted);  	}  } + +void LLMediaCtrl::updateContextMenuParent(LLView* pNewParent) +{ +	mContextMenu->updateParent(pNewParent); +} diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 5978a7a344..b07eb356ae 100755 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -168,6 +168,8 @@ public:  		LLUUID getTextureID() {return mMediaTextureID;} +		void updateContextMenuParent(LLView* pNewParent); +  	protected:  		void convertInputCoords(S32& x, S32& y); diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp index 2f65bedc2b..f7c2f629ec 100755 --- a/indra/newview/llpanelmarketplaceinboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -129,11 +129,11 @@ void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item)  // virtual  void LLInboxFolderViewFolder::draw()  { -	if (!badgeHasParent()) +	if (!hasBadgeHolderParent())  	{ -		addBadgeToParentPanel(); +		addBadgeToParentHolder();  	} -	 +  	setBadgeVisibility(mFresh);  	LLFolderViewFolder::draw(); @@ -214,9 +214,9 @@ BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)  // virtual  void LLInboxFolderViewItem::draw()  { -	if (!badgeHasParent()) +	if (!hasBadgeHolderParent())  	{ -		addBadgeToParentPanel(); +		addBadgeToParentHolder();  	}  	setBadgeVisibility(mFresh); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 8ccbb03fcc..496168229d 100755 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -159,6 +159,7 @@ public:  		registrar.add("Wearable.Create", boost::bind(onCreate, _2)); +		llassert(LLMenuGL::sMenuContainer != NULL);  		LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(  			"menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());  		llassert(menu); @@ -228,6 +229,7 @@ public:  		enable_registrar.add("AddWearable.Gear.Check", boost::bind(onCheck, flat_list_handle, inventory_panel_handle, _2));  		enable_registrar.add("AddWearable.Gear.Visible", boost::bind(onVisible, inventory_panel_handle, _2)); +		llassert(LLMenuGL::sMenuContainer != NULL);  		LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(  			"menu_add_wearable_gear.xml",  			LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 8fddd9523f..652d2be6f6 100755 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -341,6 +341,7 @@ LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()  	registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this));  	// create the context menu from the XUI +	llassert(LLMenuGL::sMenuContainer != NULL);  	return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(  		"menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());  } @@ -935,6 +936,7 @@ void LLTeleportHistoryPanel::onAccordionTabRightClick(LLView *view, S32 x, S32 y  	registrar.add("TeleportHistory.TabClose",	boost::bind(&LLTeleportHistoryPanel::onAccordionTabClose, this, tab));  	// create the context menu from the XUI +	llassert(LLMenuGL::sMenuContainer != NULL);  	mAccordionTabMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(  		"menu_teleport_history_tab.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 6a840f3f40..8708fb87ee 100755 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -273,6 +273,14 @@ void LLScreenChannel::addToast(const LLToast::Params& p)  			// only cancel notification if it isn't being used in IM session  			LLNotifications::instance().cancel(notification);  		} + +		// It was assumed that the toast would take ownership of the panel pointer. +		// But since we have decided not to display the toast, kill the panel to +		// prevent the memory leak. +		if (p.panel != NULL) +		{ +			p.panel()->die(); +		}  		return;  	} diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index a7b99a0f6b..08a4d00d0f 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -640,12 +640,26 @@ class LLVolumeGeometryManager: public LLGeometryManager  		DISTANCE_SORT  	} eSortType; -	virtual ~LLVolumeGeometryManager() { } +	LLVolumeGeometryManager(); +	virtual ~LLVolumeGeometryManager();  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group);  	void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); + +private: +	void allocateFaces(U32 pMaxFaceCount); +	void freeFaces(); + +	static int32_t sInstanceCount; +	static LLFace** sFullbrightFaces; +	static LLFace** sBumpFaces; +	static LLFace** sSimpleFaces; +	static LLFace** sNormFaces; +	static LLFace** sSpecFaces; +	static LLFace** sNormSpecFaces; +	static LLFace** sAlphaFaces;  };  //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp) diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index a27105e22d..39adfb3431 100755 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -54,6 +54,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) :	LLToastPanel(p.notif  	mAvatarName = getChild<LLTextBox>("user_name");  	mTime = getChild<LLTextBox>("time_box");  	mMessage = getChild<LLTextBox>("message"); +	mMessage->setContentTrusted(false);  	LLStyle::Params style_params;  	LLFontGL* fontp = LLViewerChat::getChatFont(); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 51935dc03b..907baf0661 100755 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -270,8 +270,12 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )      // customize panel's attributes      // is it intended for displaying a tip?      mIsTip = mNotification->getType() == "notifytip"; + +    std::string notif_name = mNotification->getName();      // is it a script dialog? -    mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup"); +    mIsScriptDialog = (notif_name == "ScriptDialog" || notif_name == "ScriptDialogGroup"); + +    bool is_content_trusted = (notif_name != "LoadWebPage");      // is it a caution?      //      // caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the @@ -314,6 +318,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )      mTextBox->setMaxTextLength(MAX_LENGTH);      mTextBox->setVisible(TRUE);      mTextBox->setPlainText(!show_images); +    mTextBox->setContentTrusted(is_content_trusted);      mTextBox->setValue(mNotification->getMessage());  	mTextBox->setIsFriendCallback(LLAvatarActions::isFriend); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 7aa0af5d93..ed26842035 100755 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1593,6 +1593,17 @@ void LLViewerMedia::cleanupClass()  {  	gIdleCallbacks.deleteFunction(LLViewerMedia::updateMedia, NULL);  	sTeleportFinishConnection.disconnect(); +	if (sSpareBrowserMediaSource != NULL) +	{ +		delete sSpareBrowserMediaSource; +		sSpareBrowserMediaSource = NULL; +	} + +	if (sCookieStore != NULL) +	{ +		delete sCookieStore; +		sCookieStore = NULL; +	}  }  ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 9d2a4a50e1..dafe2cafec 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -355,6 +355,16 @@ LLViewerShaderMgr * LLViewerShaderMgr::instance()  	return static_cast<LLViewerShaderMgr*>(sInstance);  } +// static +void LLViewerShaderMgr::releaseInstance() +{ +	if (sInstance != NULL) +	{ +		delete sInstance; +		sInstance = NULL; +	} +} +  void LLViewerShaderMgr::initAttribsAndUniforms(void)  {  	if (mReservedAttribs.empty()) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 42147fdd29..923aa522ad 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -43,6 +43,7 @@ public:  	// singleton pattern implementation  	static LLViewerShaderMgr * instance(); +	static void releaseInstance();  	void initAttribsAndUniforms(void);  	void setShaders(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b2b5c9d903..d052906bee 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -261,7 +261,7 @@ std::string	LLViewerWindow::sMovieBaseName;  LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); -class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole> +class RecordToChatConsoleRecorder : public LLError::Recorder  {  public:  	virtual void recordMessage(LLError::ELevel level, @@ -285,6 +285,22 @@ public:  	}  }; +class RecordToChatConsole : public LLSingleton<RecordToChatConsole> +{ +public: +	RecordToChatConsole() +		: LLSingleton<RecordToChatConsole>(), +		mRecorder(new RecordToChatConsoleRecorder()) +	{ +	} + +	void startRecorder() { LLError::addRecorder(mRecorder); } +	void stopRecorder() { LLError::removeRecorder(mRecorder); } + +private: +	LLError::RecorderPtr mRecorder; +}; +  ////////////////////////////////////////////////////////////////////////////  //  // LLDebugText @@ -1886,11 +1902,11 @@ void LLViewerWindow::initBase()  	// optionally forward warnings to chat console/chat floater  	// for qa runs and dev builds  #if  !LL_RELEASE_FOR_DOWNLOAD -	LLError::addRecorder(RecordToChatConsole::getInstance()); +	RecordToChatConsole::getInstance()->startRecorder();  #else  	if(gSavedSettings.getBOOL("QAMode"))  	{ -		LLError::addRecorder(RecordToChatConsole::getInstance()); +		RecordToChatConsole::getInstance()->startRecorder();  	}  #endif @@ -1907,9 +1923,7 @@ void LLViewerWindow::initBase()  	setProgressCancelButtonVisible(FALSE);  	gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder"); -  	LLMenuGL::sMenuContainer = gMenuHolder; -  }  void LLViewerWindow::initWorldUI() @@ -2039,8 +2053,7 @@ void LLViewerWindow::initWorldUI()  void LLViewerWindow::shutdownViews()  {  	// clean up warning logger -	LLError::removeRecorder(RecordToChatConsole::getInstance()); - +	RecordToChatConsole::getInstance()->stopRecorder();  	LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ;  	delete mDebugText; @@ -2075,6 +2088,9 @@ void LLViewerWindow::shutdownViews()  	// access to gMenuHolder  	cleanup_menus();  	LL_INFOS() << "menus destroyed." << LL_ENDL ; + +	view_listener_t::cleanup(); +	LL_INFOS() << "view listeners destroyed." << LL_ENDL ;  	// Delete all child views.  	delete mRootView; @@ -2150,6 +2166,12 @@ LLViewerWindow::~LLViewerWindow()  	delete mDebugText;  	mDebugText = NULL; + +	if (LLViewerShaderMgr::sInitialized) +	{ +		LLViewerShaderMgr::releaseInstance(); +		LLViewerShaderMgr::sInitialized = FALSE; +	}  } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 1f497bc107..42a7c2e576 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1917,7 +1917,10 @@ BOOL LLVOAvatarSelf::getIsCloud() const  /*static*/  void LLVOAvatarSelf::debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)  { -	gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata); +	if (gAgentAvatarp.notNull()) +	{ +		gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata); +	}  }  void LLVOAvatarSelf::debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c9f03a3b7d..945d3711f0 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4059,7 +4059,8 @@ U32 LLVOVolume::getPartitionType() const  }  LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp), +LLVolumeGeometryManager()  {  	mLODPeriod = 32;  	mDepthMask = FALSE; @@ -4070,7 +4071,8 @@ LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)  }  LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) -: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp), +LLVolumeGeometryManager()  {  	mDepthMask = FALSE;  	mLODPeriod = 32; @@ -4107,6 +4109,70 @@ bool can_batch_texture(LLFace* facep)  	return true;  } +const static U32 MAX_FACE_COUNT = 4096U; +int32_t LLVolumeGeometryManager::sInstanceCount = 0; +LLFace** LLVolumeGeometryManager::sFullbrightFaces = NULL; +LLFace** LLVolumeGeometryManager::sBumpFaces = NULL; +LLFace** LLVolumeGeometryManager::sSimpleFaces = NULL; +LLFace** LLVolumeGeometryManager::sNormFaces = NULL; +LLFace** LLVolumeGeometryManager::sSpecFaces = NULL; +LLFace** LLVolumeGeometryManager::sNormSpecFaces = NULL; +LLFace** LLVolumeGeometryManager::sAlphaFaces = NULL; + +LLVolumeGeometryManager::LLVolumeGeometryManager() +	: LLGeometryManager() +{ +	llassert(sInstanceCount >= 0); +	if (sInstanceCount == 0) +	{ +		allocateFaces(MAX_FACE_COUNT); +	} + +	++sInstanceCount; +} + +LLVolumeGeometryManager::~LLVolumeGeometryManager() +{ +	llassert(sInstanceCount > 0); +	--sInstanceCount; + +	if (sInstanceCount <= 0) +	{ +		freeFaces(); +		sInstanceCount = 0; +	} +} + +void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount) +{ +	sFullbrightFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +	sBumpFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +	sSimpleFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +	sNormFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +	sSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +	sNormSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +	sAlphaFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +} + +void LLVolumeGeometryManager::freeFaces() +{ +	ll_aligned_free<64>(sFullbrightFaces); +	ll_aligned_free<64>(sBumpFaces); +	ll_aligned_free<64>(sSimpleFaces); +	ll_aligned_free<64>(sNormFaces); +	ll_aligned_free<64>(sSpecFaces); +	ll_aligned_free<64>(sNormSpecFaces); +	ll_aligned_free<64>(sAlphaFaces); + +	sFullbrightFaces = NULL; +	sBumpFaces = NULL; +	sSimpleFaces = NULL; +	sNormFaces = NULL; +	sSpecFaces = NULL; +	sNormSpecFaces = NULL; +	sAlphaFaces = NULL; +} +  static LLTrace::BlockTimerStatHandle FTM_REGISTER_FACE("Register Face");  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) @@ -4429,16 +4495,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	mFaceList.clear(); -	const U32 MAX_FACE_COUNT = 4096; -	 -	static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*)); -	static LLFace** bump_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*)); -	static LLFace** simple_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*)); -	static LLFace** norm_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*)); -	static LLFace** spec_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*)); -	static LLFace** normspec_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*)); -	static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*)); -	  	U32 fullbright_count = 0;  	U32 bump_count = 0;  	U32 simple_count = 0; @@ -4816,7 +4872,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  						{ //can be treated as alpha mask  							if (simple_count < MAX_FACE_COUNT)  							{ -								simple_faces[simple_count++] = facep; +								sSimpleFaces[simple_count++] = facep;  							}  						}  						else @@ -4827,7 +4883,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							}  							if (alpha_count < MAX_FACE_COUNT)  							{ -								alpha_faces[alpha_count++] = facep; +								sAlphaFaces[alpha_count++] = facep;  							}  						}  					} @@ -4850,14 +4906,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  									{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)  										if (normspec_count < MAX_FACE_COUNT)  										{ -											normspec_faces[normspec_count++] = facep; +											sNormSpecFaces[normspec_count++] = facep;  										}  									}  									else  									{ //has normal map (needs texcoord1 and tangent)  										if (norm_count < MAX_FACE_COUNT)  										{ -											norm_faces[norm_count++] = facep; +											sNormFaces[norm_count++] = facep;  										}  									}  								} @@ -4865,14 +4921,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  								{ //has specular map but no normal map, needs texcoord2  									if (spec_count < MAX_FACE_COUNT)  									{ -										spec_faces[spec_count++] = facep; +										sSpecFaces[spec_count++] = facep;  									}  								}  								else  								{ //has neither specular map nor normal map, only needs texcoord0  									if (simple_count < MAX_FACE_COUNT)  									{ -										simple_faces[simple_count++] = facep; +										sSimpleFaces[simple_count++] = facep;  									}  								}									  							} @@ -4880,14 +4936,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							{ //needs normal + tangent  								if (bump_count < MAX_FACE_COUNT)  								{ -									bump_faces[bump_count++] = facep; +									sBumpFaces[bump_count++] = facep;  								}  							}  							else if (te->getShiny() || !te->getFullbright())  							{ //needs normal  								if (simple_count < MAX_FACE_COUNT)  								{ -									simple_faces[simple_count++] = facep; +									sSimpleFaces[simple_count++] = facep;  								}  							}  							else  @@ -4895,7 +4951,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  								facep->setState(LLFace::FULLBRIGHT);  								if (fullbright_count < MAX_FACE_COUNT)  								{ -									fullbright_faces[fullbright_count++] = facep; +									sFullbrightFaces[fullbright_count++] = facep;  								}  							}  						} @@ -4905,7 +4961,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							{ //needs normal + tangent  								if (bump_count < MAX_FACE_COUNT)  								{ -									bump_faces[bump_count++] = facep; +									sBumpFaces[bump_count++] = facep;  								}  							}  							else if ((te->getShiny() && LLPipeline::sRenderBump) || @@ -4913,7 +4969,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							{ //needs normal  								if (simple_count < MAX_FACE_COUNT)  								{ -									simple_faces[simple_count++] = facep; +									sSimpleFaces[simple_count++] = facep;  								}  							}  							else  @@ -4921,7 +4977,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  								facep->setState(LLFace::FULLBRIGHT);  								if (fullbright_count < MAX_FACE_COUNT)  								{ -									fullbright_faces[fullbright_count++] = facep; +									sFullbrightFaces[fullbright_count++] = facep;  								}  							}  						} @@ -4993,13 +5049,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;  	} -	genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, batch_textures, FALSE); -	genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, batch_textures); -	genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, batch_textures); -	genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE); -	genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, norm_count, FALSE, FALSE); -	genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, spec_count, FALSE, FALSE); -	genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, normspec_count, FALSE, FALSE); +	genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE); +	genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures); +	genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures); +	genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE); +	genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE); +	genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE); +	genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE);  	if (!LLPipeline::sDelayVBUpdate)  	{ diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp index 551d0be8d7..eff70ca0b2 100755 --- a/indra/newview/llwindebug.cpp +++ b/indra/newview/llwindebug.cpp @@ -45,7 +45,7 @@ public:  	~LLMemoryReserve();  	void reserve();  	void release(); -protected: +private:  	unsigned char *mReserve;  	static const size_t MEMORY_RESERVATION_SIZE;  }; @@ -53,7 +53,7 @@ protected:  LLMemoryReserve::LLMemoryReserve() :  	mReserve(NULL)  { -}; +}  LLMemoryReserve::~LLMemoryReserve()  { @@ -66,14 +66,19 @@ const size_t LLMemoryReserve::MEMORY_RESERVATION_SIZE = 5 * 1024 * 1024;  void LLMemoryReserve::reserve()  {  	if(NULL == mReserve) +	{  		mReserve = new unsigned char[MEMORY_RESERVATION_SIZE]; -}; +	} +}  void LLMemoryReserve::release()  { -	delete [] mReserve; +	if (NULL != mReserve) +	{ +		delete [] mReserve; +	}  	mReserve = NULL; -}; +}  static LLMemoryReserve gEmergencyMemoryReserve; @@ -130,6 +135,11 @@ void  LLWinDebug::init()  	}  } +void LLWinDebug::cleanup () +{ +	gEmergencyMemoryReserve.release(); +} +  void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename)  {  	// Temporary fix to switch out the code that writes the DMP file. diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h index 6f274c6f16..a3cbf6dc03 100755 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -37,6 +37,7 @@ class LLWinDebug:  public:  	static void init();  	static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL); +	static void cleanup();  private:  	static void writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename);  }; diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 10f71a2843..e42374d56b 100755 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -95,25 +95,20 @@ public:  	virtual void replay(std::ostream&) {}  }; -class LLReplayLogReal: public LLReplayLog, public LLError::Recorder, public boost::noncopyable +class RecordToTempFile : public LLError::Recorder, public boost::noncopyable  {  public: -	LLReplayLogReal(LLError::ELevel level, apr_pool_t* pool): -		mOldSettings(LLError::saveAndResetSettings()), -		mProxy(new RecorderProxy(this)), -		mTempFile("log", "", pool),		// create file -		mFile(mTempFile.getName().c_str()) // open it +	RecordToTempFile(apr_pool_t* pPool) +		: LLError::Recorder(), +		boost::noncopyable(), +		mTempFile("log", "", pPool), +		mFile(mTempFile.getName().c_str())  	{ -		LLError::setFatalFunction(wouldHaveCrashed); -		LLError::setDefaultLevel(level); -		LLError::addRecorder(mProxy);  	} -	virtual ~LLReplayLogReal() +	virtual ~RecordToTempFile()  	{ -		LLError::removeRecorder(mProxy); -		delete mProxy; -		LLError::restoreSettings(mOldSettings); +		mFile.close();  	}  	virtual void recordMessage(LLError::ELevel level, const std::string& message) @@ -121,13 +116,13 @@ public:  		mFile << message << std::endl;  	} -	virtual void reset() +	void reset()  	{  		mFile.close();  		mFile.open(mTempFile.getName().c_str());  	} -	virtual void replay(std::ostream& out) +	void replay(std::ostream& out)  	{  		mFile.close();  		std::ifstream inf(mTempFile.getName().c_str()); @@ -139,12 +134,45 @@ public:  	}  private: -	LLError::Settings* mOldSettings; -	LLError::Recorder* mProxy;  	NamedTempFile mTempFile;  	std::ofstream mFile;  }; +class LLReplayLogReal: public LLReplayLog, public boost::noncopyable +{ +public: +	LLReplayLogReal(LLError::ELevel level, apr_pool_t* pool) +		: LLReplayLog(), +		boost::noncopyable(), +		mOldSettings(LLError::saveAndResetSettings()), +		mRecorder(new RecordToTempFile(pool)) +	{ +		LLError::setFatalFunction(wouldHaveCrashed); +		LLError::setDefaultLevel(level); +		LLError::addRecorder(mRecorder); +	} + +	virtual ~LLReplayLogReal() +	{ +		LLError::removeRecorder(mRecorder); +		LLError::restoreSettings(mOldSettings); +	} + +	virtual void reset() +	{ +		boost::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->reset(); +	} + +	virtual void replay(std::ostream& out) +	{ +		boost::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->replay(out); +	} + +private: +	LLError::SettingsStoragePtr mOldSettings; +	LLError::RecorderPtr mRecorder; +}; +  class LLTestCallback : public tut::callback  {  public: | 
