fix 31411 problems interrupting imap message load r=jefft

This commit is contained in:
bienvenu%netscape.com 2000-06-21 00:34:43 +00:00
Родитель 59f179c2c6
Коммит 0f057d8ca8
4 изменённых файлов: 89 добавлений и 58 удалений

Просмотреть файл

@ -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")))
{