Thread Handling

From MozillaWiki
Jump to: navigation, search

Caveat Emptor: My understanding of all this is still evolving and I reserve the right to be a little off on some of the details below. I don't see these details in either of the books we have to allow me to check my notes for accuracy.


Thread handling in Thunderbird centers around adding and removing nsThread items to and from an nsEventQueue object.


When a new threaded action is needed a new nsThread object is created and added to the queue by calling nsThread::Dispatch(). The nsThread object references an instance of a class derived from nsIRunnable. After this item is placed on the queue the current call stack is free to return out.


When the event is processed individual nsThread items are pulled off the queue and processed by calling nsThread::ProcessNextEvent(). Inside nsThread::ProcessNextEvent() the thread's event object is referenced and its Run() method is called.


By way of example, for IMAP actions the class nsImapProtocol is derived from nsIRunnable. When a user opens an IMAP mailbox the following call stack shows how the user request becomes a thread in the queue:

 NS_InvokeByIndex()
   nsImapMailFolder::UpdateFolder()
     nsImapService::SelectFolder()
       nsImapService::GetImapConnectionAndLoadUrl()
         nsImapIncomingServer::GetImapConnectionAndLoadUrl()
           nsImapIncomingServer::GetImapConnection()
             nsImapIncomingServer::CreateProtocolInstance()
               nsImapProtocol::Initialize()
                 NS_NewThread_P()
                   nsThread::Dispatch()

The following call stack shows how this thread results in the IMAP "SELECT" command being issued to the server:

 NS_ProcessNextEvent_P()
   nsThread::ProcessNextEvent()
     nsImapProtocol::Run()
       nsImapProtocol::ImapThreadMainLoop()
         nsImapProtocol::ProcessCurrentURL()
           nsImapProtocol::ProcessSelectedStateURL()
             nsImapProtocol::SelectMailbox()
               nsImapProtocol::SendData()


POP and SMTP follow the same basic model and even have similarly named classes (e.g., nsPop3Protocol, nsPop3Service and nsPop3IncomingServer) so for now I will leave it as an exercise for the user to determine (and perhaps document) how those protocols work. I will note here that nsPop3Protocol is not derived from nsIRunnable so it must create an object (e.g., an nsSocketEvent) to give to the nsThread object. I will also note that the POP protocol queues multiple threads whereas IMAP queues a single thread. I have yet to determine what role the multiple POP threads perform.