diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 63634117b5fdd7b7cc4dfe0e4247f632d11e9a3a..21e165ebc9967e664ee5cc96fd2665cfdae4ab3e 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -578,7 +578,7 @@ LLEventTimer::LLEventTimer(const LLDate& time)
 
 LLEventTimer::~LLEventTimer()
 {
-	llassert(!mBusy); // this LLEventTimer was destroyed from its own tick() function - bad.
+	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.
 }
 
 //static
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index 8cb240c7c2618025aa99f915ce685037456c6adb..bd4fae6ab659d24beb6d2b6ca0370ad00d2b44e6 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -678,7 +678,8 @@ void LLCallFloater::resetVoiceRemoveTimers()
 
 void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
 {
-	mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
+	bool delete_it = true;
+	mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id, delete_it);
 }
 
 bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 6f9a1ccdbe0cc601d42dbf7251fa6beac7e58c7e..786fa24e659757083bd8243d519f472da9d1d432 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -205,7 +205,7 @@ void LLSpeakersDelayActionsStorage::setActionTimer(const LLUUID& speaker_id)
 	}
 }
 
-void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id)
+void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id, bool delete_it)
 {
 	if (mActionTimersMap.size() == 0) return;
 
@@ -213,7 +213,10 @@ void LLSpeakersDelayActionsStorage::unsetActionTimer(const LLUUID& speaker_id)
 
 	if (it_speaker != mActionTimersMap.end())
 	{
-		delete it_speaker->second;
+		if (delete_it)
+		{
+			delete it_speaker->second;
+		}
 		mActionTimersMap.erase(it_speaker);
 	}
 }
@@ -230,16 +233,15 @@ void LLSpeakersDelayActionsStorage::removeAllTimers()
 
 bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_id)
 {
-	unsetActionTimer(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);
 
 	if (mActionCallback)
 	{
 		mActionCallback(speaker_id);
 	}
 
-	// do not return true to avoid deleting of an timer twice:
-	// in LLSpeakersDelayActionsStorage::unsetActionTimer() & LLEventTimer::updateClass()
-	return false;
+	return true;
 }
 
 
@@ -291,7 +293,8 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
 		}
 	}
 
-	mSpeakerDelayRemover->unsetActionTimer(speakerp->mID);
+	bool delete_it = true;
+	mSpeakerDelayRemover->unsetActionTimer(speakerp->mID, delete_it);
 
 	return speakerp;
 }
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 63237204c8620e2b1e40d2ef04864471a2fe1db0..ddc3632f0753ce9227d1e0ea52e4021d1824994f 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -176,11 +176,11 @@ class LLSpeakersDelayActionsStorage
 	void setActionTimer(const LLUUID& speaker_id);
 
 	/**
-	 * Removes stored LLSpeakerActionTimer for passed speaker UUID from internal map and deletes it.
+	 * Removes stored LLSpeakerActionTimer for passed speaker UUID from internal map and optionally deletes it.
 	 *
 	 * @see onTimerActionCallback()
 	 */
-	void unsetActionTimer(const LLUUID& speaker_id);
+	void unsetActionTimer(const LLUUID& speaker_id, bool delete_it);
 
 	void removeAllTimers();
 private: