Bug 476467 "###!!! ASSERTION: child count gone negative:" when sending unsent email. r/sr=bienvenu
--- a/mailnews/compose/src/nsMsgSend.cpp
+++ b/mailnews/compose/src/nsMsgSend.cpp
@@ -264,22 +264,21 @@ NS_IMETHODIMP MsgDeliveryListener::OnSta
NS_IMETHODIMP MsgDeliveryListener::OnStopRunningUrl(nsIURI *url, nsresult aExitCode)
{
if (url)
{
nsCOMPtr<nsIMsgMailNewsUrl> mailUrl = do_QueryInterface(url);
if (mailUrl)
mailUrl->UnRegisterListener(this);
}
-
+
+ // Let mMsgSend sort out the OnStopSending notification - it knows more about
+ // the messages than we do.
if (mMsgSend)
- {
- mMsgSend->NotifyListenerOnStopSending(nsnull, aExitCode, nsnull, nsnull);
mMsgSend->SendDeliveryCallback(url, mIsNewsDelivery, aExitCode);
- }
return NS_OK;
}
/* the following macro actually implement addref, release and query interface for our component. */
NS_IMPL_THREADSAFE_ISUPPORTS1(nsMsgComposeAndSend, nsIMsgSend)
@@ -4061,20 +4060,21 @@ nsMsgComposeAndSend::DoFcc()
{
//
// Just cleanup and return success if we're not allowed to save msgs to FCC folder.
//
const char* fcc = mCompFields->GetFcc();
if (!fcc || !*fcc || !CanSaveMessagesToFolder(fcc))
{
#ifdef NS_DEBUG
- printf("\nCopy operation disabled by user!\n");
+ printf("\nCopy operation disabled by user!\n");
#endif
- NotifyListenerOnStopSending(nsnull, NS_OK, nsnull, nsnull);
+ // It is the caller's responsibility to say we've stopped sending, so just
+ // let the listeners know we're not doing a copy.
NotifyListenerOnStopCopy(NS_OK); // For closure of compose window...
return NS_OK;
}
if (mSendReport)
mSendReport->SetCurrentProcess(nsIMsgSendReport::process_Copy);
//
--- a/mailnews/compose/src/nsMsgSendLater.cpp
+++ b/mailnews/compose/src/nsMsgSendLater.cpp
@@ -356,30 +356,18 @@ SendOperationListener::OnStopSending(con
if (mSendLater)
{
if (NS_SUCCEEDED(aStatus))
{
#ifdef NS_DEBUG
printf("nsMsgSendLater: Success on the message send operation!\n");
#endif
- PRBool deleteMsgs = PR_TRUE;
-
- //
- // Now delete the message from the outbox folder.
- //
- nsCOMPtr<nsIPrefBranch> pPrefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
- if (pPrefBranch)
- pPrefBranch->GetBoolPref("mail.really_delete_draft", &deleteMsgs);
-
mSendLater->SetOrigMsgDisposition();
- if (deleteMsgs)
- {
- mSendLater->DeleteCurrentMessage();
- }
+ mSendLater->DeleteCurrentMessage();
++(mSendLater->mTotalSentSuccessfully);
}
else
{
mSendLater->NotifyListenersOnStopSending(aStatus, nsnull,
mSendLater->mTotalSendCount,
mSendLater->mTotalSentSuccessfully);
@@ -571,21 +559,16 @@ nsMsgSendLater::StartNextMailFileSend()
nsCOMPtr<nsISupports> currentItem;
rv = mEnumerator->GetNext(getter_AddRefs(currentItem));
NS_ENSURE_SUCCESS(rv, rv);
mMessage = do_QueryInterface(currentItem);
if (!mMessage)
return NS_ERROR_NOT_AVAILABLE;
- nsCOMPtr<nsIMsgDBHdr> myRDFNode ;
- myRDFNode = do_QueryInterface(mMessage, &rv);
- if(NS_FAILED(rv) || (!myRDFNode))
- return NS_ERROR_NOT_AVAILABLE;
-
mMessageFolder->GetUriForMsg(mMessage, messageURI);
rv = nsMsgCreateTempFile("nsqmail.tmp", getter_AddRefs(mTempFile));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgMessageService> messageService;
rv = GetMessageServiceFromURI(messageURI, getter_AddRefs(messageService));
if (NS_FAILED(rv) && !messageService)
@@ -698,16 +681,19 @@ nsMsgSendLater::SendUnsentMessages(nsIMs
// Notify the listeners that we are starting a send.
NotifyListenersOnStartSending(mMessagesToSend.Count());
return StartNextMailFileSend();
}
nsresult nsMsgSendLater::SetOrigMsgDisposition()
{
+ if (!mMessage)
+ return NS_ERROR_NULL_POINTER;
+
// We're finished sending a queued message. We need to look at mMessage
// and see if we need to set replied/forwarded
// flags for the original message that this message might be a reply to
// or forward of.
nsCString originalMsgURIs;
nsCString queuedDisposition;
mMessage->GetStringProperty(ORIG_URI_PROPERTY, getter_Copies(originalMsgURIs));
mMessage->GetStringProperty(QUEUED_DISPOSITION_PROPERTY, getter_Copies(queuedDisposition));
@@ -737,26 +723,35 @@ nsresult nsMsgSendLater::SetOrigMsgDispo
}
}
return NS_OK;
}
nsresult
nsMsgSendLater::DeleteCurrentMessage()
{
+ if (!mMessage)
+ {
+ NS_ERROR("nsMsgSendLater: Attempt to delete an already deleted message");
+ return NS_OK;
+ }
+
// Get the composition fields interface
nsCOMPtr<nsIMutableArray> msgArray(do_CreateInstance(NS_ARRAY_CONTRACTID));
if (!msgArray)
return NS_ERROR_FACTORY_NOT_LOADED;
msgArray->InsertElementAt(mMessage, 0, PR_FALSE);
nsresult res = mMessageFolder->DeleteMessages(msgArray, nsnull, PR_TRUE, PR_FALSE, nsnull, PR_FALSE /*allowUndo*/);
if (NS_FAILED(res))
return NS_ERROR_FAILURE;
+ // Null out the message so we don't try and delete it again.
+ mMessage = nsnull;
+
return NS_OK;
}
//
// This function parses the headers, and also deletes from the header block
// any headers which should not be delivered in mail, regardless of whether
// they were present in the queue file. Such headers include: BCC, FCC,
// Sender, X-Mozilla-Status, X-Mozilla-News-Host, and Content-Length.
--- a/mailnews/compose/test/unit/test_bug474774.js
+++ b/mailnews/compose/test/unit/test_bug474774.js
@@ -39,16 +39,17 @@ msll.prototype = {
// XXX Do we really need this?
},
onStopSending: function (aStatus, aMsg, aTotal, aSuccessful) {
do_test_finished();
print("msll onStopSending\n");
try {
do_check_eq(aStatus, 0);
do_check_eq(aTotal, 1);
+ do_check_eq(aSuccessful, 1);
do_check_eq(this._initialTotal, 1);
do_check_eq(msgSendLater.sendingMessages, false);
do_check_transaction(transaction,
["EHLO test",
"MAIL FROM:<" + kSender + "> SIZE=" + originalData.length,
"RCPT TO:<" + kTo + ">",
"DATA"]);
@@ -197,20 +198,16 @@ function sendMessageLater()
thread.processNextEvent(true);
}
}
function run_test() {
// Test file - for bug 429891
originalData = loadFileToString(testFile);
- Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch)
- .setBoolPref("mail.really_delete_draft", false);
-
// Ensure we have a local mail account, an normal account and appropriate
// servers and identities.
loadLocalMailAccount();
var acctMgr = Cc["@mozilla.org/messenger/account-manager;1"]
.getService(Ci.nsIMsgAccountManager);
acctMgr.setSpecialFolders();
--- a/mailnews/compose/test/unit/test_sendMessageLater.js
+++ b/mailnews/compose/test/unit/test_sendMessageLater.js
@@ -46,16 +46,17 @@ msll.prototype = {
// XXX Do we really need this?
},
onStopSending: function (aStatus, aMsg, aTotal, aSuccessful) {
do_test_finished();
print("msll onStopSending\n");
try {
do_check_eq(aStatus, 0);
do_check_eq(aTotal, 1);
+ do_check_eq(aSuccessful, 1);
do_check_eq(this._initialTotal, 1);
do_check_eq(msgSendLater.sendingMessages, false);
do_check_transaction(transaction,
["EHLO test",
"MAIL FROM:<" + kSender + "> SIZE=" + originalData.length,
"RCPT TO:<" + kTo + ">",
"DATA"]);
@@ -204,20 +205,16 @@ function sendMessageLater()
thread.processNextEvent(true);
}
}
function run_test() {
// Test file - for bug 429891
originalData = loadFileToString(testFile);
- Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch)
- .setBoolPref("mail.really_delete_draft", false);
-
// Ensure we have a local mail account, an normal account and appropriate
// servers and identities.
loadLocalMailAccount();
var acctMgr = Cc["@mozilla.org/messenger/account-manager;1"]
.getService(Ci.nsIMsgAccountManager);
acctMgr.setSpecialFolders();