IMAP

  • Revision slug: IMAP
  • Revision title: IMAP
  • Revision id: 34747
  • Created:
  • Creator: DavidBienvenu
  • Is current revision? No
  • Comment

Revision Content

The IMAP protocol implementation is the most complicated in the mailnews code, though IMAP is by far the most complicated protocol as well.

The IMAP implementation is the only multi-threaded protocol in mailnews. The other protocols use necko to do the actual socket i/o on a separate thread, but everything else, including the parsing of the server responses, happens on the main UI thread. In IMAP, we spin up a new thread for every connection to the server, and read from the input nsPipe and parse the responses on that thread. This allows us to write code as if the sending of commands and the retrieving of responses was synchronous, e.g., this code here where we send the select mailbox command, and parse the server response in the next line of code. In contrast, POP3/NNTP/SMTP all send commands and receive responses using a state machine.

At the time the IMAP code was originally written, it was felt that the state machine approach would just be too complicated, and make the code hard to maintain. The trade-off is that we have to deal with thread safety issues, deadlock, etc. The biggest problem we have right now is that there are times when we try to shutdown connections from the UI thread, and we end up calling methods on the UI thread that should only be called from the IMAP thread.

Generally, almost all the code in nsImapProtocol, and all the parsing code (nsImapServerResponseParser, nsImapGenericParser, and nsImapBodyShell) are run on the imap connection thread. When an imap thread needs to communicate with the UI thread, the nsImapProtocol object uses one of three xpcom proxy sink objects - nsIImapMailFolderSink, nsIImapServerSink, and nsIImapMessageSink.

Revision Source

<p>The <a class="external" href="http://www.faqs.org/rfcs/rfc3501.html">IMAP protocol</a> implementation is the most complicated in the mailnews code, though IMAP is by far the most complicated protocol as well.
</p><p>The IMAP implementation is the only multi-threaded protocol in mailnews. The other protocols use necko to do the actual socket i/o on a separate thread, but everything else, including the parsing of the server responses, happens on the main UI thread. In IMAP, we spin up a new thread for every connection to the server, and read from the input nsPipe and parse the responses on that thread. This allows us to write code as if the sending of commands and the retrieving of responses was synchronous, e.g., this code <a class="external" href="http://mxr.mozilla.org/mozilla/source/mailnews/imap/src/nsImapProtocol.cpp#2777">here</a> where we send the select mailbox command, and parse the server response in the next line of code. In contrast, POP3/NNTP/SMTP all send commands and receive responses using a state machine.
</p><p>At the time the IMAP code was originally written, it was felt that the state machine approach would just be too complicated, and make the code hard to maintain. The trade-off is that we have to deal with thread safety issues, deadlock, etc. The biggest problem we have right now is that there are times when we try to shutdown connections from the UI thread, and we end up calling methods on the UI thread that should only be called from the IMAP thread.
</p><p>Generally, almost all the code in nsImapProtocol, and all the parsing code (nsImapServerResponseParser, nsImapGenericParser, and nsImapBodyShell) are run on the imap connection thread. When an imap thread needs to communicate with the UI thread, the nsImapProtocol object uses one of three xpcom proxy sink objects - <a class="external" href="http://mxr.mozilla.org/mozilla/source/mailnews/imap/public/nsIImapMailFolderSink.idl#68">nsIImapMailFolderSink</a>, <a class="external" href="http://mxr.mozilla.org/mozilla/source/mailnews/imap/public/nsIImapServerSink.idl#47">nsIImapServerSink</a>, and <a class="external" href="http://mxr.mozilla.org/mozilla/source/mailnews/imap/public/nsIImapMessageSink.idl#46">nsIImapMessageSink</a>.
</p>
Revert to this revision