diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 21e165ebc9967e664ee5cc96fd2665cfdae4ab3e..900e122ea516422a2ed80097c63d985f9e33ceaa 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -560,45 +560,44 @@ void secondsToTimecodeString(F32 current_time, std::string& tcstring)
 //		LLEventTimer Implementation
 //
 //////////////////////////////////////////////////////////////////////////////
+bool LLEventTimer::sInTickLoop = false;
 
 LLEventTimer::LLEventTimer(F32 period)
 : mEventTimer()
 {
 	mPeriod = period;
-	mBusy = false;
 }
 
 LLEventTimer::LLEventTimer(const LLDate& time)
 : mEventTimer()
 {
 	mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
-	mBusy = false;
 }
 
 
 LLEventTimer::~LLEventTimer()
 {
-	llassert(!mBusy); // this LLEventTimer was destroyed from within its own tick() function - bad.  if you want tick() to cause destruction of its own timer, make it return true.
+	llassert(!LLEventTimer::sInTickLoop); // this LLEventTimer was destroyed from within its own tick() function - bad.  if you want tick() to cause destruction of its own timer, make it return true.
 }
 
 //static
 void LLEventTimer::updateClass() 
 {
 	std::list<LLEventTimer*> completed_timers;
+	LLEventTimer::sInTickLoop = true;
 	for (instance_iter iter = beginInstances(); iter != endInstances(); ) 
 	{
 		LLEventTimer& timer = *iter++;
 		F32 et = timer.mEventTimer.getElapsedTimeF32();
 		if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
 			timer.mEventTimer.reset();
-			timer.mBusy = true;
 			if ( timer.tick() )
 			{
 				completed_timers.push_back( &timer );
 			}
-			timer.mBusy = false;
 		}
 	}
+	LLEventTimer::sInTickLoop = false;
 
 	if ( completed_timers.size() > 0 )
 	{
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index 4d995d5bba2f2dc8bbdb20dfd4f228f81e69a1f2..63e8121b58a3b9adcbbd0c5a9a11add7e8ac2341 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -188,7 +188,7 @@ class LL_COMMON_API LLEventTimer : protected LLInstanceTracker<LLEventTimer>
 protected:
 	LLTimer mEventTimer;
 	F32 mPeriod;
-	bool mBusy;
+	static bool sInTickLoop;
 };
 
 U64 LL_COMMON_API totalTime();					// Returns current system time in microseconds
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index d405c1bbc141304468be19ca6e9dd9737f938428..97a5c3b8e22d14bdd5863f67688af99dcf41273d 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -678,8 +678,7 @@ void LLCallFloater::resetVoiceRemoveTimers()
 
 void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
 {
-	bool delete_it = true;
-	mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id, delete_it);
+	mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
 }
 
 bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 786fa24e659757083bd8243d519f472da9d1d432..717a8bda1e561e8fa1a94625da302058ac252781 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -175,6 +175,11 @@ BOOL LLSpeakerActionTimer::tick()
 	return TRUE;
 }
 
+void LLSpeakerActionTimer::unset()
+{
+	mActionCallback = 0;
+}
+
 LLSpeakersDelayActionsStorage::LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay)
 : mActionCallback(action_cb)
 , mActionDelay(action_delay)
@@ -205,7 +210,7 @@ void LLSpeakersDelayActionsStorage::setActionTimer(const LLUUID& speaker_id)
 	}
 }
 
-void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id, bool delete_it)
+void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id)
 {
 	if (mActionTimersMap.size() == 0) return;
 
@@ -213,10 +218,7 @@ void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id, b
 
 	if (it_speaker != mActionTimersMap.end())
 	{
-		if (delete_it)
-		{
-			delete it_speaker->second;
-		}
+		it_speaker->second->unset();
 		mActionTimersMap.erase(it_speaker);
 	}
 }
@@ -233,8 +235,7 @@ void LLSpeakersDelayActionsStorage::removeAllTimers()
 
 bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_id)
 {
-	bool delete_it = false; // we're *in* this timer, return true to delete it, don't manually delete it
-	unsetActionTimer(speaker_id, delete_it);
+	unsetActionTimer(speaker_id);
 
 	if (mActionCallback)
 	{
@@ -293,9 +294,7 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
 		}
 	}
 
-	bool delete_it = true;
-	mSpeakerDelayRemover->unsetActionTimer(speakerp->mID, delete_it);
-
+	mSpeakerDelayRemover->unsetActionTimer(speakerp->mID);
 	return speakerp;
 }
 
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index ddc3632f0753ce9227d1e0ea52e4021d1824994f..9fa46d0650c92897e61491d7892048a72c0470a9 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -155,6 +155,13 @@ class LLSpeakerActionTimer : public LLEventTimer
 	 */
 	virtual BOOL tick();
 
+	/**
+	 * Clears the callback.
+	 *
+	 * Use this instead of deleteing this object. 
+	 * The next call to tick() will return true and that will destroy this object.
+	 */
+	void unset();
 private:
 	action_callback_t	mActionCallback;
 	LLUUID				mSpeakerId;
@@ -180,7 +187,7 @@ class LLSpeakersDelayActionsStorage
 	 *
 	 * @see onTimerActionCallback()
 	 */
-	void unsetActionTimer(const LLUUID& speaker_id, bool delete_it);
+	void unsetActionTimer(const LLUUID& speaker_id);
 
 	void removeAllTimers();
 private:
@@ -188,7 +195,6 @@ class LLSpeakersDelayActionsStorage
 	 * Callback of the each instance of LLSpeakerActionTimer.
 	 *
 	 * Unsets an appropriate timer instance and calls action callback for specified speacker_id.
-	 * It always returns false to not use LLEventTimer::updateClass functionality of timer deleting.
 	 *
 	 * @see unsetActionTimer()
 	 */