зеркало из https://github.com/mozilla/pjs.git
fix 31411 problems interrupting imap message load r=jefft
This commit is contained in:
Родитель
59f179c2c6
Коммит
0f057d8ca8
|
@ -59,6 +59,12 @@
|
|||
#include "nsIMsgMailNewsUrl.h"
|
||||
#include "nsIImapService.h"
|
||||
#include "nsMsgI18N.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsIImapMockChannel.h"
|
||||
// for the memory cache...
|
||||
#include "nsINetDataCacheManager.h"
|
||||
#include "nsINetDataCache.h"
|
||||
#include "nsICachedNetData.h"
|
||||
|
||||
#include "nsITimer.h"
|
||||
static NS_DEFINE_CID(kCImapHostSessionList, NS_IIMAPHOSTSESSIONLIST_CID);
|
||||
|
@ -355,7 +361,6 @@ nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue * aClientEventQu
|
|||
// queue
|
||||
PR_CEnterMonitor(this);
|
||||
nsCOMPtr <nsISupports> supports(do_QueryInterface(aImapUrl));
|
||||
// printf("queueing imap url \n");
|
||||
if (supports)
|
||||
m_urlQueue->AppendElement(supports);
|
||||
m_urlConsumers.AppendElement((void*)aConsumer);
|
||||
|
@ -374,13 +379,13 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
|
|||
PRUint32 cnt = 0;
|
||||
nsresult rv = NS_OK;
|
||||
PRBool urlRun = PR_FALSE;
|
||||
PRBool removeUrlFromQueue = PR_FALSE;
|
||||
PRBool keepGoing = PR_TRUE;
|
||||
|
||||
PR_CEnterMonitor(this);
|
||||
nsAutoCMonitor(this);
|
||||
m_urlQueue->Count(&cnt);
|
||||
|
||||
// printf("loading next url, cnt = %ld\n", cnt);
|
||||
|
||||
if (cnt > 0)
|
||||
while (cnt > 0 && !urlRun && keepGoing)
|
||||
{
|
||||
nsCOMPtr<nsISupports>
|
||||
aSupport(getter_AddRefs(m_urlQueue->ElementAt(0)));
|
||||
|
@ -389,37 +394,78 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
|
|||
|
||||
if (aImapUrl)
|
||||
{
|
||||
nsISupports *aConsumer =
|
||||
(nsISupports*)m_urlConsumers.ElementAt(0);
|
||||
nsCOMPtr <nsIImapMockChannel> mockChannel;
|
||||
nsCOMPtr<nsIURI> url(do_QueryInterface(aSupport, &rv));
|
||||
|
||||
NS_IF_ADDREF(aConsumer);
|
||||
|
||||
nsCOMPtr <nsIImapProtocol> protocolInstance ;
|
||||
rv = CreateImapConnection(nsnull, aImapUrl,
|
||||
getter_AddRefs(protocolInstance));
|
||||
if (NS_SUCCEEDED(rv) && protocolInstance)
|
||||
if (NS_SUCCEEDED(aImapUrl->GetMockChannel(getter_AddRefs(mockChannel))) && mockChannel)
|
||||
{
|
||||
mockChannel->GetStatus(&rv);
|
||||
if (!NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsresult res;
|
||||
removeUrlFromQueue = PR_TRUE;
|
||||
|
||||
mockChannel->Close(); // try closing it to get channel listener nulled out.
|
||||
|
||||
nsCOMPtr<nsINetDataCacheManager> cacheManager = do_GetService(NS_NETWORK_CACHE_MANAGER_PROGID, &res);
|
||||
if (NS_SUCCEEDED(res) && cacheManager)
|
||||
{
|
||||
nsCOMPtr<nsICachedNetData> cacheEntry;
|
||||
// Retrieve an existing cache entry or create a new one if none exists for the
|
||||
// given URL.
|
||||
nsXPIDLCString urlCString;
|
||||
// eventually we are going to want to use the url spec - the query/ref part 'cause that doesn't
|
||||
// distinguish urls.......
|
||||
url->GetSpec(getter_Copies(urlCString));
|
||||
// for now, truncate of the query part so we don't duplicate urls in the cache...
|
||||
char * anchor = PL_strrchr(urlCString, '?');
|
||||
if (anchor)
|
||||
*anchor = '\0';
|
||||
res = cacheManager->GetCachedNetData(urlCString, 0, 0, nsINetDataCacheManager::BYPASS_PERSISTENT_CACHE,
|
||||
getter_AddRefs(cacheEntry));
|
||||
if (NS_SUCCEEDED(res) && cacheEntry)
|
||||
cacheEntry->Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Note that we're relying on no one diddling the rv from the mock channel status
|
||||
// between the place we set it and here.
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsISupports *aConsumer =
|
||||
(nsISupports*)m_urlConsumers.ElementAt(0);
|
||||
|
||||
NS_IF_ADDREF(aConsumer);
|
||||
|
||||
nsCOMPtr <nsIImapProtocol> protocolInstance ;
|
||||
rv = CreateImapConnection(nsnull, aImapUrl,
|
||||
getter_AddRefs(protocolInstance));
|
||||
if (NS_SUCCEEDED(rv) && protocolInstance)
|
||||
{
|
||||
nsCOMPtr<nsIURI> url = do_QueryInterface(aImapUrl, &rv);
|
||||
if (NS_SUCCEEDED(rv) && url)
|
||||
{
|
||||
rv = protocolInstance->LoadUrl(url, aConsumer);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed running queued url");
|
||||
urlRun = PR_TRUE;
|
||||
removeUrlFromQueue = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
keepGoing = PR_FALSE;
|
||||
NS_IF_RELEASE(aConsumer);
|
||||
}
|
||||
if (removeUrlFromQueue)
|
||||
{
|
||||
nsCOMPtr<nsIURI> url = do_QueryInterface(aImapUrl, &rv);
|
||||
if (NS_SUCCEEDED(rv) && url)
|
||||
{
|
||||
#ifdef DEBUG_bienvenu
|
||||
printf("loading queued url\n");
|
||||
#endif
|
||||
rv = protocolInstance->LoadUrl(url, aConsumer);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed running queued url");
|
||||
urlRun = PR_TRUE;
|
||||
}
|
||||
m_urlQueue->RemoveElementAt(0);
|
||||
m_urlConsumers.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(aConsumer);
|
||||
}
|
||||
m_urlQueue->Count(&cnt);
|
||||
}
|
||||
if (aResult)
|
||||
*aResult = urlRun;
|
||||
|
||||
PR_CExitMonitor(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -784,31 +784,9 @@ NS_IMETHODIMP nsImapMailFolder::GetNoSelect(PRBool *aResult)
|
|||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
return GetFlag(MSG_FOLDER_FLAG_IMAP_NOSELECT, aResult);
|
||||
}
|
||||
#ifdef DEBUG_bienvenu1
|
||||
nsIMsgSearchSession *saveSearchSession;
|
||||
#endif
|
||||
NS_IMETHODIMP nsImapMailFolder::Compact()
|
||||
{
|
||||
nsresult rv;
|
||||
#ifdef DEBUG_bienvenu1
|
||||
nsCOMPtr<nsIMsgSearchSession> searchSession;
|
||||
rv = nsComponentManager::CreateInstance(NS_MSGSEARCHSESSION_PROGID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIMsgSearchSession),
|
||||
getter_AddRefs(searchSession));
|
||||
if (searchSession)
|
||||
{
|
||||
nsMsgSearchValue *searchValue = new nsMsgSearchValue;
|
||||
searchValue->u.string = PL_strdup("test");
|
||||
searchValue->attribute = nsMsgSearchAttrib::Subject;
|
||||
searchSession->AddSearchTerm(nsMsgSearchAttrib::Subject, nsMsgSearchOp::Contains,
|
||||
searchValue, PR_FALSE, nsnull);
|
||||
searchSession->AddScopeTerm(nsMsgSearchScope::MailFolder, this);
|
||||
saveSearchSession = searchSession;
|
||||
NS_ADDREF(saveSearchSession);
|
||||
searchSession->Search(nsnull);
|
||||
}
|
||||
#endif
|
||||
NS_WITH_SERVICE(nsIImapService, imapService, kCImapService, &rv);
|
||||
if (NS_SUCCEEDED(rv) && imapService)
|
||||
{
|
||||
|
@ -3325,10 +3303,6 @@ NS_IMETHODIMP
|
|||
nsImapMailFolder::NotifySearchHit(nsIMsgMailNewsUrl * aUrl,
|
||||
const char* searchHitLine)
|
||||
{
|
||||
#ifdef DEBUG_bienvenu
|
||||
printf("search hit %s\n", searchHitLine);
|
||||
#endif
|
||||
|
||||
nsresult rv = GetDatabase(nsnull /* don't need msg window, that's more for local mbox parsing */);
|
||||
if (!mDatabase || !NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
|
|
|
@ -833,6 +833,8 @@ nsImapProtocol::PseudoInterruptMsgLoad(nsIImapUrl *aImapUrl, PRBool *interrupted
|
|||
{
|
||||
NS_ENSURE_ARG (interrupted);
|
||||
|
||||
*interrupted = PR_FALSE;
|
||||
|
||||
nsAutoCMonitor(this);
|
||||
|
||||
if (m_runningUrl && !TestFlag(IMAP_CLEAN_UP_URL_STATE))
|
||||
|
@ -863,8 +865,9 @@ nsImapProtocol::PseudoInterruptMsgLoad(nsIImapUrl *aImapUrl, PRBool *interrupted
|
|||
}
|
||||
}
|
||||
}
|
||||
// this should check if the protocol instance is currently running a msg fetch
|
||||
// url for the passed folder, and if so, pseudo interrupt it.
|
||||
#ifdef DEBUG_bienvenu
|
||||
printf("interrupt msg load : %s\n", (*interrupted) ? "TRUE" : "FALSE");
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -965,6 +968,9 @@ PRBool nsImapProtocol::ProcessCurrentURL()
|
|||
PRBool logonFailed = PR_FALSE;
|
||||
PRBool anotherUrlRun = PR_FALSE;
|
||||
|
||||
|
||||
PseudoInterrupt(PR_FALSE); // clear this if left over from previous url.
|
||||
|
||||
if (!TestFlag(IMAP_CONNECTION_IS_OPEN) && m_channel)
|
||||
{
|
||||
m_channel->AsyncRead(this /* stream observer */, nsnull);
|
||||
|
@ -1090,8 +1096,6 @@ PRBool nsImapProtocol::ProcessCurrentURL()
|
|||
rv = m_channelListener->OnStopRequest(m_mockChannel, m_channelContext, NS_OK, nsnull);
|
||||
|
||||
m_lastActiveTime = PR_Now(); // ** jt -- is this the best place for time stamp
|
||||
PseudoInterrupt(PR_FALSE); // clear this, because we must be done
|
||||
// interrupting?
|
||||
SetFlag(IMAP_CLEAN_UP_URL_STATE);
|
||||
if (NS_SUCCEEDED(rv) && GetConnectionStatus() >= 0 && GetServerStateParser().LastCommandSuccessful()
|
||||
&& m_imapMiscellaneousSink && m_runningUrl)
|
||||
|
@ -1375,7 +1379,8 @@ NS_IMETHODIMP nsImapProtocol::IsBusy(PRBool *aIsConnectionBusy,
|
|||
if (m_urlInProgress) // do we have a url? That means we're working on it...
|
||||
*aIsConnectionBusy = PR_TRUE;
|
||||
|
||||
if (GetServerStateParser().GetSelectedMailboxName() &&
|
||||
if (GetServerStateParser().GetIMAPstate() ==
|
||||
nsImapServerResponseParser::kFolderSelected && GetServerStateParser().GetSelectedMailboxName() &&
|
||||
PL_strcasecmp(GetServerStateParser().GetSelectedMailboxName(),
|
||||
"Inbox") == 0)
|
||||
*isInboxConnection = PR_TRUE;
|
||||
|
@ -3385,7 +3390,9 @@ PRMonitor *nsImapProtocol::GetDataMemberMonitor()
|
|||
PRBool nsImapProtocol::DeathSignalReceived()
|
||||
{
|
||||
nsresult returnValue = NS_OK;
|
||||
if (m_mockChannel)
|
||||
// ignore mock channel status if we've been pseudo interrupted
|
||||
// ### need to make sure we clear pseudo interrupted status appropriately.
|
||||
if (!GetPseudoInterrupted() && m_mockChannel)
|
||||
m_mockChannel->GetStatus(&returnValue);
|
||||
|
||||
if (NS_SUCCEEDED(returnValue)) // check the other way of cancelling.
|
||||
|
|
|
@ -384,7 +384,11 @@ void nsImapServerResponseParser::ProcessOkCommand(const char *commandToken)
|
|||
!PL_strcasecmp(commandToken, "EXAMINE"))
|
||||
fIMAPstate = kFolderSelected;
|
||||
else if (!PL_strcasecmp(commandToken, "CLOSE"))
|
||||
{
|
||||
fIMAPstate = kAuthenticated;
|
||||
// we no longer have a selected mailbox.
|
||||
PR_FREEIF( fSelectedMailboxName );
|
||||
}
|
||||
else if ((!PL_strcasecmp(commandToken, "LIST")) ||
|
||||
(!PL_strcasecmp(commandToken, "LSUB")))
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче