From 65301bc0ccb6ed53e5b29471d64fab552fb9744d Mon Sep 17 00:00:00 2001 From: "bienvenu%netscape.com" Date: Wed, 1 May 2002 20:48:03 +0000 Subject: [PATCH] fix crash on shutdown when duplicate mail db listeners have been registered r=naving, sr=sspitzer 141028 --- mailnews/db/msgdb/src/nsMsgDatabase.cpp | 71 ++++++++++++++----------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/mailnews/db/msgdb/src/nsMsgDatabase.cpp b/mailnews/db/msgdb/src/nsMsgDatabase.cpp index 9b3058daa54..4ed80f5a6ed 100644 --- a/mailnews/db/msgdb/src/nsMsgDatabase.cpp +++ b/mailnews/db/msgdb/src/nsMsgDatabase.cpp @@ -440,28 +440,32 @@ nsMsgDatabase::CreateMsgHdr(nsIMdbRow* hdrRow, nsMsgKey key, nsIMsgDBHdr* *resul NS_IMETHODIMP nsMsgDatabase::AddListener(nsIDBChangeListener *listener) { - if (m_ChangeListeners == nsnull) - { - m_ChangeListeners = new nsVoidArray(); - if (!m_ChangeListeners) - return NS_ERROR_OUT_OF_MEMORY; - } - return m_ChangeListeners->AppendElement(listener); + if (m_ChangeListeners == nsnull) + { + m_ChangeListeners = new nsVoidArray(); + if (!m_ChangeListeners) + return NS_ERROR_OUT_OF_MEMORY; + } + // check if this listener is already registered + // if already registered, do nothing (not an error) + else if (m_ChangeListeners->IndexOf(listener) != -1) + return NS_OK; + return m_ChangeListeners->AppendElement(listener); } NS_IMETHODIMP nsMsgDatabase::RemoveListener(nsIDBChangeListener *listener) { - if (m_ChangeListeners == nsnull) - return NS_OK; - for (PRInt32 i = 0; i < m_ChangeListeners->Count(); i++) - { - if ((nsIDBChangeListener *) m_ChangeListeners->ElementAt(i) == listener) - { - m_ChangeListeners->RemoveElementAt(i); - return NS_OK; - } - } - return NS_COMFALSE; + if (m_ChangeListeners == nsnull) + return NS_OK; + for (PRInt32 i = 0; i < m_ChangeListeners->Count(); i++) + { + if ((nsIDBChangeListener *) m_ChangeListeners->ElementAt(i) == listener) + { + m_ChangeListeners->RemoveElementAt(i); + return NS_OK; + } + } + return NS_COMFALSE; } // change announcer methods - just broadcast to all listeners. @@ -556,20 +560,20 @@ NS_IMETHODIMP nsMsgDatabase::NotifyParentChangedAll(nsMsgKey keyReparented, nsMs NS_IMETHODIMP nsMsgDatabase::NotifyAnnouncerGoingAway(void) { - if (m_ChangeListeners == nsnull) - return NS_OK; - // run loop backwards because listeners remove themselves from the list - // on this notification - for (PRInt32 i = m_ChangeListeners->Count() - 1; i >= 0 ; i--) - { - nsIDBChangeListener *changeListener = - (nsIDBChangeListener *) m_ChangeListeners->ElementAt(i); - - nsresult rv = changeListener->OnAnnouncerGoingAway(this); - if (NS_FAILED(rv)) - return rv; - } + if (m_ChangeListeners == nsnull) return NS_OK; + // run loop backwards because listeners remove themselves from the list + // on this notification + for (PRInt32 i = m_ChangeListeners->Count() - 1; i >= 0 ; i--) + { + nsIDBChangeListener *changeListener = + (nsIDBChangeListener *) m_ChangeListeners->ElementAt(i); + + nsresult rv = changeListener->OnAnnouncerGoingAway(this); + if (NS_FAILED(rv)) + return rv; + } + return NS_OK; } @@ -1070,6 +1074,11 @@ NS_IMETHODIMP nsMsgDatabase::ForceClosed() m_mdbStore->Release(); m_mdbStore = nsnull; } + if (m_ChangeListeners) + { + // better not be any listeners, because we're going away. + NS_ASSERTION(m_ChangeListeners->Count() == 0, "shouldn't have any listeners left"); + } Release(); return err; }