We weren't creating the socket transport from the correct thread. We were

doing it from LoadUrl which is in the ui thread. Necko makes assumptions
about what event queue to use for pumping notification messages based on
the current thread when you create the socket. So I moved this code
into ProcessCurrentUrl which lives in the imap connectoin thread.
Also fixed a big problem where we would wait on a monitor but waiting
was preventing messages from getting pumped which prevented ODA from
being called. So the monitor could never get notified. The fix is to
timeout of the PR_Wait and pump message events. We can then check a
flag to see if messages are being pumped.
This commit is contained in:
mscott%netscape.com 1999-08-10 23:18:37 +00:00
Родитель 0375e0b94d
Коммит a7dd00b829
2 изменённых файлов: 27 добавлений и 14 удалений

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

@ -804,7 +804,14 @@ void nsImapProtocol::EstablishServerConnection()
void nsImapProtocol::ProcessCurrentURL()
{
PRBool logonFailed = FALSE;
if (!TestFlag(IMAP_CONNECTION_IS_OPEN))
{
nsCOMPtr<nsISupports> sprts = do_QueryInterface (m_runningUrl);
m_channel->AsyncRead(0, -1, sprts,this /* stream observer */);
SetFlag(IMAP_CONNECTION_IS_OPEN);
}
// we used to check if the current running url was
// Reinitialize the parser
GetServerStateParser().InitializeState();
@ -953,6 +960,7 @@ NS_IMETHODIMP nsImapProtocol::OnDataAvailable(nsIChannel * /* aChannel */, nsISu
// if we received data, we need to signal the data available monitor...
// Read next line from input will actually read the data out of the stream
ClearFlag(IMAP_WAITING_FOR_DATA); // we are no longer waiting for data
PR_EnterMonitor(m_dataAvailableMonitor);
PR_Notify(m_dataAvailableMonitor);
PR_ExitMonitor(m_dataAvailableMonitor);
@ -1090,12 +1098,7 @@ nsresult nsImapProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
// we're pulling out a selected state connection, but maybe we
// can get away with this.
m_needNoop = (imapAction == nsIImapUrl::nsImapSelectFolder || imapAction == nsIImapUrl::nsImapDeleteAllMsgs);
if (!TestFlag(IMAP_CONNECTION_IS_OPEN))
{
nsCOMPtr<nsISupports> sprts = do_QueryInterface (m_runningUrl);
m_channel->AsyncRead(0, -1, sprts,this /* stream observer */);
SetFlag(IMAP_CONNECTION_IS_OPEN);
}
// We now have a url to run so signal the monitor for url ready to be processed...
PR_EnterMonitor(m_urlReadyToRunMonitor);
m_nextUrlReadyToRun = PR_TRUE;
@ -3390,15 +3393,24 @@ char* nsImapProtocol::CreateNewLineFromSocket()
newLine = m_inputStreamBuffer->ReadNextLine(m_inputStream, numBytesInLine, needMoreData);
if (needMoreData)
{
// wait on the data available monitor!!
PR_EnterMonitor(m_dataAvailableMonitor);
// wait for data arrival
PR_Wait(m_dataAvailableMonitor, PR_INTERVAL_NO_TIMEOUT);
PR_ExitMonitor(m_dataAvailableMonitor);
// once data has arrived, recursively
SetFlag(IMAP_WAITING_FOR_DATA);
// we want to put this thread to rest until the on data available monitor goes off..
// so sleep until the timeout hits, then pump some events. This may cause the IMAP_WAITING_FOR_DATA
// flag to get cleared which means data has arrived so we can kick out of the loop or the
// death signal may have been received which means we should still kick out of the loop.
do
{
// wait on the data available monitor!!
PR_EnterMonitor(m_dataAvailableMonitor);
// wait for data arrival
PR_Wait(m_dataAvailableMonitor, /* PR_INTERVAL_NO_TIMEOUT */ 50);
PR_ExitMonitor(m_dataAvailableMonitor);
// now that we are awake...process some events
m_eventQueue->ProcessPendingEvents();
} while (TestFlag(IMAP_WAITING_FOR_DATA) && !DeathSignalReceived());
}
} while (!newLine && !DeathSignalReceived()); // until we get the next line and haven't been interrupted
} while (!newLine); // until we get the next line and haven't been interrupted
Log("CreateNewLineFromSocket", nsnull, newLine);
SetConnectionStatus(newLine ? PL_strlen(newLine) : 0);

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

@ -52,6 +52,7 @@ class nsIWebShell;
#define IMAP_RECEIVED_GREETING 0x00000001 /* should we pause for the next read */
#define IMAP_FIRST_PASS_IN_THREAD 0x00000002 /* entering thread for the first time? */
#define IMAP_CONNECTION_IS_OPEN 0x00000004 /* is the connection currently open? */
#define IMAP_WAITING_FOR_DATA 0x00000008
class nsImapProtocol : public nsIImapProtocol
{