Closed
Bug 103883
Opened 23 years ago
Closed 23 years ago
[MLK] Using Preference observers is prone to reference cycles
Categories
(Core :: Preferences: Backend, defect)
Core
Preferences: Backend
Tracking
()
RESOLVED
FIXED
People
(Reporter: bnesse, Assigned: bnesse)
Details
(Keywords: memory-leak)
Attachments
(3 files, 4 obsolete files)
63.84 KB,
patch
|
alecf
:
superreview+
|
Details | Diff | Splinter Review |
6.15 KB,
patch
|
Details | Diff | Splinter Review | |
6.18 KB,
patch
|
jag+mozilla
:
review+
alecf
:
superreview+
|
Details | Diff | Splinter Review |
As a number of people have discovered, I think I have cc'd you all, registering
as a prefs observer is prone to causing cyclical references with the preferences
branch. Based on some discussions that stemmed from bug 102332 I have worked up
a patch in an attempt to reduce these cycles.
The patch takes a 2 pronged approach. First, the nsPrefBranch object now listens
for the xpcom-shutdown message and releases all of the observers in its list.
This releases the observing object from having to do the same, which appears to
be the direction current patches are heading. Second, I have added a parameter
to the AddObserver call |aHoldWeak|. If the observing object supports weak
reference and passes in PR_TRUE for this parameter the nsPrefBranch object will
hold a weak reference to the object in its observer list.
Hopefully I will get the patch attached before Darin and crew add the
xpcom-shutdown fix to any more files in the netwerk library. ;)
Assignee | ||
Comment 1•23 years ago
|
||
Comment 2•23 years ago
|
||
i gave the patch a once over and it looks pretty good to me. r=darin on the
libpref and necko changes.
Comment 3•23 years ago
|
||
Question: even if the observing object doesn't support weak references,
releasing the observers on xpcom-shutdown should break the reference cycle, right?
Comment 4•23 years ago
|
||
mstolz: yup.. however, waiting for xpcom-shutdown may not be appropriate for all
obsevers. one could imagine a short lived object that Adds itself as a pref
observer in its constructor and removes itself in its destructor... code like
this would only work if the prefbranch supported weak references.
Comment 5•23 years ago
|
||
Comment on attachment 52744 [details] [diff] [review]
Proposed patch
there have been debates about putting html markup in comments..not that
you've done that per say, but you've put <true> and <false> in brackets. true
or |true| should be fine..
in freeObserverList, domain should be nsAutoCString.
Also, I moved nsCharsetMenu to xpfe/intl, though I think
I haven't yet removed the one in intl/uconv/src it from the mac build..
any chance you can remove it from the project? :)
sr=alecf with those changes
Assignee | ||
Comment 6•23 years ago
|
||
I was wondering why there were 2 copies of nsCharsetMenu.cpp. I'd be more than
happy to remove it... I was very, very scared when I found the second one... :)
I'll kill the brackets... I was going to revisit the documentation anyway. I
still want to add a note about holding a weak reference to the prefBranch object
and notate the work covered by this patch.
Assignee | ||
Comment 7•23 years ago
|
||
Assignee | ||
Updated•23 years ago
|
Attachment #52744 -
Attachment is obsolete: true
Assignee | ||
Comment 8•23 years ago
|
||
Mitch, could you please review the nsScriptSecurityManager changes?
Gordon, can you review the nsCacheService changes?
Seth, can you review the nsDBFolderInfo changes, or suggest someone on your team
who can?
And, finally, can someone (there's no clear owner) review the nsCharSetMenu
changes? Thanks.
r=gordon for the changes to nsDNSService.cpp and nsCacheService.cpp.
Assignee | ||
Comment 10•23 years ago
|
||
Assignee | ||
Updated•23 years ago
|
Attachment #52777 -
Attachment is obsolete: true
Comment 11•23 years ago
|
||
I'm so glad this is being done :-)
r=ccarlen on changes to nsCharsetMenu.cpp
One thing, though not added in this patch, there are quite a few occurences:
Shouldn't NS_PREFBRANCH_PREFCHANGE_OBSERVER_ID be called
NS_PREFBRANCH_PREFCHANGE_TOPIC_ID? That would be more readable as well as more
accurate.
Assignee | ||
Comment 12•23 years ago
|
||
That's a good suggestion. Since I just added the define, this would be the time
to change it. I'm going to have to regenerate the patch anyway... I just
discovered some JS exceptions being thrown. :( I'm not sure why I didn't notice
them before...
Comment 13•23 years ago
|
||
coolness. I'm with conrad, and I'm glad we caught it early..
Comment 14•23 years ago
|
||
r=mstoltz on the change to nsScriptSecurityManager.
Comment 15•23 years ago
|
||
Comment on attachment 52968 [details] [diff] [review]
Fixed one bug in RemoveObserver() as per email with Darin.
actually marking sr=alecf
Attachment #52968 -
Flags: superreview+
Comment 16•23 years ago
|
||
the mailnews changes seem ok.
instead of :
if (pls != NULL) {
}
why not:
if (pls) {
}
Comment 17•23 years ago
|
||
also, do we want to check the return value from
+ rv = prefBranch->GetComplexValue(kMAILNEWS_VIEW_DEFAULT_CHARSET,
+ NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls));
or is checking if pls is non null the right thing to do?
I'd think we'd check rv, something like
if (NS_SUCCEEDED(rv)) {
}
or
if (NS_SUCCEEDED(rv) && pls) {
|
Comment 18•23 years ago
|
||
bnesse, I think we need to make sure that getComplexValue() follows the same
semantics as QueryInterface - i.e. a success always means that the result has a
value... then we should be checking if (NS_SUCCEEDED(rv))
Assignee | ||
Comment 19•23 years ago
|
||
Seth, thanks for the input, I will clean up accordingly. Alec, yes, success ==
valid value... I'll double check that an empty preference is returned as a 0
length string, but I'm pretty sure it is.
Assignee | ||
Comment 20•23 years ago
|
||
Comment 21•23 years ago
|
||
r=hewitt for the changes to PrefUtils.js, InspectorSidebar.js, and
urlbarBindings.xml. Although, I should note that InspectorSidebar.js is a dead
file that isn't used. I should just cvs remove it...
Comment 22•23 years ago
|
||
cc'ing dougt who is doing this change for the observer service... we should make
sure the semantics of this are the same. I have no strong feelings one way or
the other for "holdweak" vs. "holdstrong"
Assignee | ||
Comment 23•23 years ago
|
||
Agreed. I went with holdweak because the "default" functionality for the prefs
service is to "hold strong", because that's the only kind of hold it supported.
Unfortunately the default (existing) functionality of ObserverService is to
"hold weak" if the object supports it...
Personally, I feel that holdweak is better because it singles out what I
consider to be the special case condition (i.e. I support weak reference and I
wish to be held that way).
Comment 24•23 years ago
|
||
In MsgComposeCommands.js:
How about declaring a global pbi and initilaizing it in ComposeLoad() instead
of declaring it in several functions.
+ var pbi = prefs.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
Other than this, changes in MsgComposeCommands.js, navigator.js, fastnav.js
looks ok to me.
Comment 25•23 years ago
|
||
brian, I am with you. I will be adding a new parameter to
nsIObserverService::AddObserver called holdWeak to that we will have a
consistant looking api.
Comment 26•23 years ago
|
||
regarding srilatha's comment: the convention is to say:
const nsIPrefBranchInternal = Components.interfaces.nsIPrefBranchInternal
that way when you're reading code that later uses this, it is obvious that it's
a reference to an interface. (Also note the use of "const")
Comment 27•23 years ago
|
||
i vote for "holdweak" :-)
Comment 28•23 years ago
|
||
what darin said. :-)
Assignee | ||
Comment 29•23 years ago
|
||
Assignee | ||
Updated•23 years ago
|
Attachment #54103 -
Attachment is obsolete: true
Assignee | ||
Updated•23 years ago
|
Attachment #52968 -
Attachment is obsolete: true
Comment 30•23 years ago
|
||
Comment on attachment 54211 [details] [diff] [review]
Final patch reflecting srilatha's comments
cool, looks good.. thanks for switching these files over to nsIPrefBranch,
too. Make sure to test the heck out of compose, on the off chance that there
are not other .js files in this window using the global "prefs" variable.
Attachment #54211 -
Flags: superreview+
Comment 31•23 years ago
|
||
r=srilatha on the changes in MsgComposeCommands.js, fastnav.js and navigator.js
Assignee | ||
Comment 32•23 years ago
|
||
Fix is in. Hopefully we'll see a drop in leaks. :)
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Comment 33•23 years ago
|
||
Comment on attachment 54211 [details] [diff] [review]
Final patch reflecting srilatha's comments
>Index: mozilla/xpfe/browser/resources/content/navigator.js
>===================================================================
>RCS file: /cvsroot/mozilla/xpfe/browser/resources/content/navigator.js,v
>retrieving revision 1.380
>diff -u -2 -r1.380 navigator.js
>--- navigator.js 2001/10/13 02:26:30 1.380
>+++ navigator.js 2001/10/18 19:36:24
>@@ -205,5 +205,7 @@
> {
> try {
>- pref.addObserver(this.domain, this);
>+ var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
>+ if (pbi)
>+ pbi.addObserver(this.domain, this, false);
No need for the |if (pbi)|, the QI will throw an exception when it fails.
> } catch(ex) {
> dump("Failed to observe prefs: " + ex + "\n");
>@@ -276,4 +278,11 @@
> throw "couldn't create a browser instance";
>
>+ // Get the preferences service
>+ var prefService = Components.classes["@mozilla.org/preferences-service;1"]
>+ .getService(Components.interfaces.nsIPrefService);
>+ if (!prefService)
>+ throw "couldn't create a preferences service";
No need to throw here manually, .getService() will throw when it fails.
>+ pref = prefService.getBranch(null);
>+
> webNavigation = getWebNavigation();
> if (!webNavigation)
>@@ -448,6 +457,8 @@
>
> // unregister us as a pref listener
>- pref.removeObserver(window.buttonPrefListener.domain,
>- window.buttonPrefListener);
>+ var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
>+ if (pbi)
>+ pbi.removeObserver(window.buttonPrefListener.domain,
>+ window.buttonPrefListener);
No need for the |if (pbi)|, the QI will throw an exception when it fails.
>@@ -950,5 +962,5 @@
> BrowserViewSourceOfURL(url.replace(/^view-source:/, ""), null);
> } else {
>- if (pref && pref.GetBoolPref("browser.tabs.opentabfor.urlbar") && getBrowser().localName == "tabbrowser") {
>+ if (pref && pref.getBoolPref("browser.tabs.opentabfor.urlbar") && getBrowser().localName == "tabbrowser") {
> var t = getBrowser().addTab(getShortcutOrURI(url)); // open link in new tab
> getBrowser().selectedTab = t;
>@@ -1368,5 +1380,7 @@
> chromeRegistry.uninstallSkin( themeName.getAttribute("name"), true );
> // XXX - this sucks and should only be temporary.
>- pref.SetUnicharPref("general.skins.removelist." + themeName.getAttribute("name"), true);
>+ pref.setComplexValue("general.skins.removelist." + themeName.getAttribute("name"),
>+ Components.interfaces.nsISupportsWString,
>+ true);
>
> if (inUse)
>@@ -1380,5 +1394,7 @@
> // we STILL haven't fixed editor skin switch problems
> // hacking around it yet again
>- pref.SetUnicharPref("general.skins.selectedSkin", themeName.getAttribute("name"));
>+ pref.setComplexValue("general.skins.selectedSkin",
>+ Components.interfaces.nsISupportsWString,
>+ themeName.getAttribute("name"));
>
> var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
For some reason this code doesn't work. When trying to switch to another
theme from the view menu, I got this error:
JavaScript error:
line 0: uncaught exception: [Exception... "Could not convert JavaScript
argument arg 2 [nsIPrefBranch.setComplexValue]" nsresult: "0x80570009
(NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame ::
chrome://navigator/content/navigator.js :: applyTheme :: line 1393" data: no]
Assignee | ||
Comment 34•23 years ago
|
||
jag, see bug 106159. Could this could be the reverse of that? nsIPref global
stomping on nsIPrefBranch somehow...
Reopening until we get a resolution...
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Comment 35•23 years ago
|
||
I just realized that the reason the last bit doesn't work (the setComplexValue)
is that we need to actually create an nsISupportsWString and set the data in it,
and pass THAT into setComplexValue - XPConnect isn't smart enough (and it won't
ever be :)) to make that conversion...
Assignee | ||
Comment 36•23 years ago
|
||
Comment 37•23 years ago
|
||
could this be the reason for bug 106309 as well?
Assignee | ||
Comment 38•23 years ago
|
||
I doubt it. I don't really see what the connection would be bug 106309 doesn't
appear to have any preference related issues.
Assignee | ||
Comment 39•23 years ago
|
||
Can I get r/sr on attachment 54737 [details] [diff] [review] so I can land the fix for the theme switch
bug? Thanks.
Comment 40•23 years ago
|
||
Comment on attachment 54737 [details] [diff] [review]
Patch which eliminates error, addresses jag's comments, and fixes theme switching.
looks almost right, but you're going to cause some JS warnings because you're not declaring "str"
try turning on JS warnings in the "Debug" panel - you'll be amazed at what you see :)
Assignee | ||
Comment 41•23 years ago
|
||
Crap... I've had this little voice in the back of my head all day telling me I
forgot to put a "var" somewhere.... these are the only files I didn't double
check. :(
Assignee | ||
Comment 42•23 years ago
|
||
Comment 43•23 years ago
|
||
Comment on attachment 54787 [details] [diff] [review]
Better patch with no JS warnings :)
sr=alecf
Attachment #54787 -
Flags: superreview+
Comment 44•23 years ago
|
||
Comment on attachment 54787 [details] [diff] [review]
Better patch with no JS warnings :)
r=jag
Attachment #54787 -
Flags: review+
Assignee | ||
Comment 45•23 years ago
|
||
Fix checked in.
Status: REOPENED → RESOLVED
Closed: 23 years ago → 23 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•