Closed
Bug 383489
Opened 17 years ago
Closed 15 years ago
IMAP code touches the pref service from off the main thread
Categories
(MailNews Core :: Backend, defect, P2)
MailNews Core
Backend
Tracking
(Not tracked)
RESOLVED
FIXED
Thunderbird 3.1a1
People
(Reporter: bzbarsky, Assigned: Bienvenu)
Details
Attachments
(2 files, 1 obsolete file)
(deleted),
patch
|
Bienvenu
:
review+
Bienvenu
:
superreview+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
neil
:
review+
neil
:
superreview+
standard8
:
approval-thunderbird3-
|
Details | Diff | Splinter Review |
The pref service is not threadsafe (see bug 380315). The IMAP code touches preferences from off-thread in nsImapProtocol::TryToLogon:
7545 nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
7546 if (NS_SUCCEEDED(rv) && prefBranch)
7547 prefBranch->GetBoolPref("mail.auth_login", &prefBool);
Flags: blocking1.9?
Reporter | ||
Updated•17 years ago
|
Flags: blocking-thunderbird3?
Comment 1•17 years ago
|
||
is this a regression?
Reporter | ||
Comment 2•17 years ago
|
||
I have no idea, to be honest. There've been IMAP threading changes since 1.8, but I don't know whether they affected this.
Comment 3•17 years ago
|
||
Per discussion in m.d.a.seamonkey minusing this for 1.9 - if it is a core bug and seamonkey or tbird need this in the 1.9 timeframe please do re-nominate.
Flags: blocking1.9? → blocking1.9-
Assignee | ||
Comment 4•17 years ago
|
||
Not a regression - the fix would be in the imap code, so it wouldn't affect gecko.
Updated•17 years ago
|
Assignee: nobody → ebirol
Comment 5•17 years ago
|
||
Additionally, is the following code thread-safe?
PRBool nsImapProtocol::TryToLogon()
{
....
....
// get the password and user name for the current incoming server...
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(m_server);
if (server)
{
// we are in the imap thread so *NEVER* try to extract the password with UI
// if logon redirection has changed the password, use the cookie as the password
if (m_overRideUrlConnectionInfo)
password.Assign(m_logonCookie);
else
rv = server->GetPassword(password);
rv = server->GetRealUsername(userName);
}
What guarantees that "server" is not set to nsnull by another thread just after the 'if(server)' statement and just before the 'server->' call?
Does XPCOM weak referencing mechanism prevent such cases? Or this is something we should address in the code?
Assignee | ||
Comment 6•17 years ago
|
||
if you mean the server might be deleted from an other thread, that shouldn't happen because the comptr holds a strong ref to the server object. Code from an other thread couldn't clear out the local variable on the stack.
Comment 7•17 years ago
|
||
> Code from an other thread couldn't clear out the local variable on the stack.
Yes it cannot but this is not the case here. "if (server)" is not testing a local variable on the stack, it's testing the raw pointer wrapped by the local variable type of nsCOMPtr<> using 'operator nsDerivedSafe<T>*() const' implicit conversion function. Same here for the -> operator. So, according to Weak reference documentation this pointer can become a nsnull anytime.. But also says that Weak refs are not thread-safe! I thought that maybe that's why we are keep getting
###!!! ASSERTION: nsStreamListenerTee not thread-safe: '_mOwningThread.GetThread() == PR_GetCurrentThread()'
assertion in case of bug 410747.
Having said that, I understand now that since m_server is a strong ref and it's a member of imapprotocol class, unless imapprotocol instance goes away, it is safe to use weak ref on m_server.
This leads me to the question; is it safe to create a weak ref from a strong ref created by another thread. Because every imapprotocol instance therefore m_server ref is created by UI thread.
XPCOM and reference counting give me headache.
Assignee | ||
Comment 8•17 years ago
|
||
Yes, it gives me a headache as well. As I understand it, m_server is a weak ref, but the local comptr is a strong ref to the underlying object that m_server is a weak ref to. But either way, there's a strong ref to the server object so it shouldn't go away.
nsMsgIncomingServer supports threadsafe addrefs and remove refs, and I believe it's the underlying object that really handles the weakref stuff. I think it's OK to do what we're doing, as long as we're careful. I'm pretty sure the assertion doesn't have to do with that. I haven't seen that assertion in a while, so I forget what causes it.
Comment 9•17 years ago
|
||
>m_server is a weak ref, but the local comptr is a strong ref to the underlying >object that m_server is a weak ref to. But either way, there's a strong ref to >the server object so it shouldn't go away.
Didn't realize that m_server is declared as weak reference in imapprotocol. That also explains why it is not allowed to use WeakReference pointers directly.
also noticed that I've pasted wrong assertion to commment #7. The following one was concerning me;
##!!! ASSERTION: nsWeakReference not thread-safe: '_mOwningThread.GetThread()
== PR_GetCurrentThread()', file nsWeakReference.cpp, line 146
Assignee | ||
Comment 10•17 years ago
|
||
Ah, that one I think you're right about. What does the rest of the stack look like? If it's when the protocol object is getting destroyed, we need to be destroying that weak ref on the same thread that we created it. Either we need to make sure the protocol object is destroyed on the ui thread, or we need to clear the weak ref on the ui thread. If it's the mock channel stuff when we retry a url, we need to try to do the mock channel stuff on the ui thread...I'll look into it.
Updated•17 years ago
|
OS: Linux → All
Hardware: PC → All
Comment 11•17 years ago
|
||
One of the places we get this assertion is in CloseStreams() when m_server is set to nsnull by protocol thread. Perfectly inline with your explanation. Also explains why I don't get this assertion when I proxy TellThreadToDie over UI thread.
Updated•16 years ago
|
Product: Core → MailNews Core
Comment 12•16 years ago
|
||
Emre: is the status of this bug up to date?
Looks like it might be a blocker if it's still happening.
Flags: blocking-thunderbird3? → blocking-thunderbird3+
Priority: -- → P2
Target Milestone: --- → Thunderbird 3.0b2
Comment 13•16 years ago
|
||
Yes, it is up-to-date and should be fixed as soon as possible by proxying GetBoolPref("mail.auth_login", &prefBool); call.
I will try to come up with a patch before beta1.
Assignee | ||
Comment 14•16 years ago
|
||
ugh, instead of proxying, which is heavy weight, involves changing the interface, etc, how about making the call in SetupWithUrl or some other routine that we know is called from the ui thread, and caching the result in the protocol object?
Comment 15•16 years ago
|
||
David, thoughts.
Assignee | ||
Comment 16•16 years ago
|
||
Comment on attachment 348067 [details] [diff] [review]
Proposed fix
the var name should be m_authLogin; I think the comment is probably too specific - in general, we're doing a bunch of setup that needs to run on the UI thread, but will later be accessed on the imap thread. A comment to that effect would be helpful.
Assignee | ||
Comment 17•16 years ago
|
||
actually, looking at the exisitng comment in the code, it says what you're doing should be in ::Initialize() - so if you could put it there, that would be good.
Comment 18•16 years ago
|
||
Member name is changed, initialization i moved to ::Initialize
Attachment #348067 -
Attachment is obsolete: true
Assignee | ||
Comment 19•16 years ago
|
||
Comment on attachment 348125 [details] [diff] [review]
Take 2
looks good, thx
Attachment #348125 -
Flags: superreview+
Attachment #348125 -
Flags: review+
Assignee | ||
Comment 20•16 years ago
|
||
fix checked in, changeset: 1133:4ccd97dc684c
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → FIXED
Updated•16 years ago
|
Target Milestone: Thunderbird 3.0b2 → Thunderbird 3.0b1
Assignee | ||
Comment 21•15 years ago
|
||
maybe this regressed, but we're still touching the prefs service indirectly from the imap thread. Patch upcoming.
Status: RESOLVED → REOPENED
Flags: blocking-thunderbird3+
Resolution: FIXED → ---
Assignee | ||
Comment 22•15 years ago
|
||
GetRealUsername reads the username from prefs, which means the imap thread reads prefs. This fix makes us proxy the read over to the ui thread.
w/o this fix, I often can't run my builds because the ui thread and the imap thread access prefs at the same time, which makes prefs assert like crazy.
Assignee: bugmil.ebirol → bienvenu
Attachment #412338 -
Flags: superreview?(neil)
Attachment #412338 -
Flags: review?(neil)
Updated•15 years ago
|
Attachment #412338 -
Flags: superreview?(neil)
Attachment #412338 -
Flags: superreview+
Attachment #412338 -
Flags: review?(neil)
Attachment #412338 -
Flags: review+
Assignee | ||
Comment 23•15 years ago
|
||
fix checked in. I don't know if we'd want to consider this for 3.0x - I don't know that it has release build ramifications, but it sure hoses debug builds.
Status: REOPENED → RESOLVED
Closed: 16 years ago → 15 years ago
Resolution: --- → FIXED
Target Milestone: Thunderbird 3.0b1 → Thunderbird 3.1a1
Updated•15 years ago
|
Target Milestone: Thunderbird 3.1a1 → Thunderbird 3.0b1
Updated•15 years ago
|
Target Milestone: Thunderbird 3.0b1 → Thunderbird 3.1a1
Comment 24•15 years ago
|
||
Comment on attachment 412338 [details] [diff] [review]
proposed fix
The only way we can take this is if we put it into 3.0 (due to the idl changes), flagging for approval for now (for discussion later).
Attachment #412338 -
Flags: approval-thunderbird3?
Comment 25•15 years ago
|
||
Comment on attachment 412338 [details] [diff] [review]
proposed fix
From the sounds of it we don't think this will fix anything in particular, therefore not taking for 3.0 at the moment to reduce the risk.
Attachment #412338 -
Flags: approval-thunderbird3? → approval-thunderbird3-
You need to log in
before you can comment on or make changes to this bug.
Description
•