Closed
Bug 831993
Opened 12 years ago
Closed 12 years ago
convert nsISupportsArray m_serversToGetNewMailFor variable from nsPop3IncomingServer.cpp to something better
Categories
(MailNews Core :: Networking: POP, defect)
MailNews Core
Networking: POP
Tracking
(Not tracked)
RESOLVED
FIXED
Thunderbird 22.0
People
(Reporter: aceman, Assigned: neil)
References
Details
Attachments
(1 file, 4 obsolete files)
(deleted),
patch
|
standard8
:
review+
rkent
:
feedback+
|
Details | Diff | Splinter Review |
Defined as a variable in:
mailnews/local/src/nsPop3IncomingServer.cpp (View Hg log or Hg annotations)
line 46 -- nsCOMPtr <nsISupportsArray> m_serversToGetNewMailFor;
line 676 -- m_serversToGetNewMailFor = servers;
line 711 -- m_serversToGetNewMailFor->Count(&numServersLeft);
line 716 -- m_serversToGetNewMailFor->RemoveElementAt(0);
Referenced in:
mailnews/local/src/nsPop3IncomingServer.cpp (View Hg log or Hg annotations)
line 715 -- nsCOMPtr <nsIPop3IncomingServer> popServer (do_QueryElementAt(m_serversToGetNewMailFor, 0));
Attachment #703598 -
Flags: feedback?(kent)
This alternative version makes m_serversToGetNewMailFor nsIArray as it seems we do not really need to alter it. However this crashes in tests, so there is a bug somewhere.
Attachment #703637 -
Flags: feedback?(kent)
Attachment #703637 -
Flags: feedback?(neil)
Assignee | ||
Comment 3•12 years ago
|
||
Note: this compiles but is otherwise untested.
Ideally I would use nsCOMArray<nsIPop3IncomingServer> throughout but that would require either a [noscript] version of downloadMailFromServers or the nsCOMArray improvements awaiting review in bug 493711.
Assignee | ||
Comment 4•12 years ago
|
||
Comment on attachment 703637 [details] [diff] [review]
WIP patch 2
> uint32_t numServersLeft;
>- m_serversToGetNewMailFor->Count(&numServersLeft);
>+ m_serversToGetNewMailFor->GetLength(&numServersLeft);
>
>- for (; numServersLeft > 0;)
>+ while (numServersLeft > 0)
> {
>- nsCOMPtr <nsIPop3IncomingServer> popServer (do_QueryElementAt(m_serversToGetNewMailFor, 0));
>- m_serversToGetNewMailFor->RemoveElementAt(0);
>+ nsCOMPtr<nsIPop3IncomingServer> popServer =
>+ do_QueryElementAt(m_serversToGetNewMailFor, numServersLeft - 1);
> numServersLeft--;
The old code ends up enumerating the servers in ascending order because it removes the first one each time. The new code enumerates the servers in descending order. This could be the cause of your problem. Or I might just be clutching at straws...
Attachment #703637 -
Flags: feedback?(neil) → feedback+
Comment on attachment 703874 [details] [diff] [review]
Alternative approach
I can't say I understand what this new patch does. Passing in a nsTArray is interesting :)
Attachment #703874 -
Flags: feedback?(kent)
(In reply to neil@parkwaycc.co.uk from comment #4)
> The old code ends up enumerating the servers in ascending order because it
> removes the first one each time. The new code enumerates the servers in
> descending order. This could be the cause of your problem. Or I might just
> be clutching at straws...
Sure, I can change that, probably at the cost of a new variable that runs up to the numServersLeft.
Were you able to find the problem why this version crashes?
Assignee | ||
Comment 7•12 years ago
|
||
No, and you're going to need a stack trace if you want me to look harder.
For some reason the tests do not crash today. So let's see which version does rkent like.
Attachment #703637 -
Attachment is obsolete: true
Attachment #703637 -
Flags: feedback?(kent)
Attachment #704019 -
Flags: feedback?(kent)
Comment 9•12 years ago
|
||
Comment on attachment 704019 [details] [diff] [review]
WIP patch 2 v2
Overall this looks good. I prefer this approach.
Just as an aside, ironically today I was checking some old code of mine where I did exactly what I told you NOT to do yesterday, that is to pass in an nsIArray then QI to nsIMutableArray. Not sure why did did that :(
Attachment #704019 -
Flags: feedback?(kent) → feedback+
Comment 10•12 years ago
|
||
Comment on attachment 703874 [details] [diff] [review]
Alternative approach
I don't really understand the value of using raw XPCOM arrays, with the need to pass count and do careful NS_IF_RELEASE() when nsIMutableArray is a perfectly valid replacement.
Attachment #703874 -
Flags: feedback?(kent) → feedback-
Comment 11•12 years ago
|
||
Comment on attachment 703598 [details] [diff] [review]
WIP patch
Isn't this obsolete, or is there some reason I need to look at it as well? If the question is whether nsIArray or nsIMutableArray is used, I would only use nsIMutableArray into a method that you know is going to change the array.
(diff service is temporarily offline so I cannot easily see the changes).
Attachment #703598 -
Flags: feedback?(kent)
Assignee | ||
Comment 12•12 years ago
|
||
(In reply to Kent James from comment #10)
> I don't really understand the value of using raw XPCOM arrays, with the need
> to pass count and do careful NS_IF_RELEASE() when nsIMutableArray is a
> perfectly valid replacement.
As I said, this really wants the nsCOMArray improvements in bug 493711, then there wouldn't be any need for manual refcounting. (The value comes from the array being typesafe; nsIMutableArray could contain anything.)
Comment 13•12 years ago
|
||
Typesafe is an advantage. I really appreciate how my C++ code generates compile errors when someone changes an interface, but the javascript code only fails when you try to run it.
Reporter | ||
Comment 14•12 years ago
|
||
(In reply to Kent James (:rkent) from comment #11)
> Comment on attachment 703598 [details] [diff] [review]
> WIP patch
>
> Isn't this obsolete, or is there some reason I need to look at it as well?
> If the question is whether nsIArray or nsIMutableArray is used, I would only
> use nsIMutableArray into a method that you know is going to change the array.
>
> (diff service is temporarily offline so I cannot easily see the changes).
The differene between "WIP patch" and "WIP patch 2 (v2)" is that in WIP patch I used mutable arrays and had to copy one array as one interface had an nsIArray in argument. The "WIP patch 2" solves it all with nsIArray as it seems we do not really need to alter the array internally (of course I can't say if there isn't any leak now). So I prefer the version 2, as it probably allows the caller to pass in mutable or immutable array as he sees fit.
Assignee | ||
Comment 15•12 years ago
|
||
Note: this version needs the patch from bug 493711 that I'll attach shortly, but I just want to show you how much cleaner the code is when you have a useful nsCOMArray API :-)
Attachment #704319 -
Flags: feedback?(kent)
Comment 16•12 years ago
|
||
Comment on attachment 704319 [details] [diff] [review]
Alternative approach
So I have mixed feelings about this, Neil. The issue comes down to what you fear most, and what I fear most is refcount errors and crashes from nulls.
So I see stuff like:
sresult nsPop3GetMailChainer::GetNewMailForServers(nsIPop3IncomingServer** servers ...
then
m_serversToGetNewMailFor.AppendElements(servers, count);
and I start asking what happened to the memory that was allocated for servers. Or was it allocated? I don't know, so I would have to look in detail at the memory model issues associated with .Elements() and .AppendElements.
You'll probably tell me that one of the simplifications of this is that the memory allocation is handled automatically, but I don't know that so I would have to look at it in more detail.
I still like the type safety though.
I also see that you are not protecting for null values in calls like rv = deferredServers[0]-> so once again I would have to check in details the code for nsCOMArray to see if it does the protection.
So this forces me to learn a new set of issues associated with an object that is fairly rarely used. In my own code, I would not bother (at least for usage through XPCOM. As an internal variable in a C++ method I would use nsCOMArray.)
This of course is just my opinion, and reflects my own skill level (or lack thereof).
Attachment #704319 -
Flags: feedback?(kent)
Assignee | ||
Comment 17•12 years ago
|
||
(In reply to Kent James from comment #16)
> So I see stuff like:
>
> sresult nsPop3GetMailChainer::GetNewMailForServers(nsIPop3IncomingServer**
> servers ...
>
> then
>
> m_serversToGetNewMailFor.AppendElements(servers, count);
>
> and I start asking what happened to the memory that was allocated for
> servers. Or was it allocated? I don't know, so I would have to look in
> detail at the memory model issues associated with .Elements() and
> .AppendElements.
Under the XPCOM interface contract, servers is a read-only array of pointers (to mutable objects, although that's not relevant here). AppendElements copies the array into its local mutable nsCOMArray (and also AddRefs them, so that the caller is free to Release its copies).
> I also see that you are not protecting for null values in calls like rv =
> deferredServers[0]-> so once again I would have to check in details the code
> for nsCOMArray to see if it does the protection.
No, it doesn't, but my version of GetDeferredServers only returns non-null POP3 servers, since it happens to save a call to QueryInterface. (If the old code had been using my test for a deferred server then it wouldn't have had to null-check the server either.)
Reporter | ||
Comment 18•12 years ago
|
||
So what now?
Assignee | ||
Updated•12 years ago
|
Attachment #703874 -
Attachment is obsolete: true
Assignee | ||
Comment 19•12 years ago
|
||
Comment on attachment 704319 [details] [diff] [review]
Alternative approach
OK, so this uses the new improved nsCOMArray from bug 493711.
>- nsCOMPtr <nsIMsgIncomingServer> server (do_QueryElementAt(allServers, i));
>+ nsCOMPtr<nsIPop3IncomingServer> server(do_QueryElementAt(allServers, i));
> if (server)
This now ensures that only actual nsIPop3IncomingServer objects get added to the array. The change in nsNoIncomingServer relies on this.
>- void downloadMailFromServers(in nsISupportsArray aServers,
>- in nsIMsgWindow aMsgWindow,
>- in nsIMsgFolder aFolder,
>- in nsIUrlListener aListener);
>+ void downloadMailFromServers(
>+ [array, size_is(count)]in nsIPop3IncomingServer aServers,
>+ in unsigned long count, in nsIMsgWindow aMsgWindow,
>+ in nsIMsgFolder aFolder, in nsIUrlListener aListener);
This means that the function is still scriptable. (But I haven't updated the callers yet.)
>- m_serversToGetNewMailFor = servers;
>+ m_serversToGetNewMailFor.AppendElements(servers, count);
The old code used an nsISupportsArray so you just had to add a new reference to that array to make it keep its contents. The new code uses an array of XPCOM pointers so that the elements of the array have to be appended to a local array. Fortunately the new nsCOMArray makes that easy.
>+ nsCOMPtr<nsIPop3IncomingServer> popServer(m_serversToGetNewMailFor[0]);
>+ m_serversToGetNewMailFor.RemoveObjectAt(0);
> numServersLeft--;
> if (popServer)
I left this null-check in as the array could have come from script and therefore potentially contain null elements.
Attachment #704319 -
Flags: feedback?(kent)
Comment 20•12 years ago
|
||
Comment on attachment 704319 [details] [diff] [review]
Alternative approach
I like this approach with the new nsCOMArray. Memory management seems to be much cleaner, which is what you would hope for with a custom array type.
Attachment #704319 -
Flags: feedback?(kent) → feedback+
Assignee | ||
Updated•12 years ago
|
Attachment #704319 -
Flags: review?(mbanner)
Reporter | ||
Comment 21•12 years ago
|
||
rkent, would you mind reviewing this when you already saw it, or do we need to wait for standard8?
Or did Neil choose standard8 intentionally?
Flags: needinfo?(kent)
Attachment #704019 -
Attachment is obsolete: true
Attachment #703598 -
Attachment is obsolete: true
Comment 22•12 years ago
|
||
I would be willing to review this if requested by Neil or Standard8 to do so.
Flags: needinfo?(kent)
Comment 23•12 years ago
|
||
Comment on attachment 704319 [details] [diff] [review]
Alternative approach
Review of attachment 704319 [details] [diff] [review]:
-----------------------------------------------------------------
::: mailnews/local/public/nsIPop3IncomingServer.idl
@@ -29,5 @@
> attribute ACString deferredToAccount;
> // whether get new mail in deferredToAccount gets
> // new mail with this server.
> attribute boolean deferGetNewMail;
> - void downloadMailFromServers(in nsISupportsArray aServers,
This file needs a uuid change.
Attachment #704319 -
Flags: review?(mbanner) → review+
Assignee | ||
Comment 24•12 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Reporter | ||
Comment 25•12 years ago
|
||
This seem to have caused failures in mail/test/mozmill/instrumentation/test-instrument-setup.js like this:
[Exception... "Not enough arguments [nsIPop3IncomingServer.downloadMailFromServers]" nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)" location: "JS frame :: chrome://messenger/conte
nt/mailWindowOverlay.js :: MsgGetMessagesForAllServers :: line 1433" data: no]
But the test still passes, that is why it was not detected.
It seems "Get all mail" does not work for POP3 servers in TB now.
Neil, can you audit all callers of the changed DownloadMailFromServers ?
Flags: needinfo?(neil)
Comment 26•12 years ago
|
||
I just created bug 855631 for SeaMonkey because of the get all mails problem.
Reporter | ||
Comment 27•12 years ago
|
||
Thanks for confirmation. So we can move over there.
Flags: needinfo?(neil)
Updated•12 years ago
|
Target Milestone: --- → Thunderbird 22.0
You need to log in
before you can comment on or make changes to this bug.
Description
•