Closed
Bug 107617
Opened 23 years ago
Closed 23 years ago
Adding an observer to a non-toplevel prefbranch doesn't work
Categories
(Core :: Preferences: Backend, defect)
Core
Preferences: Backend
Tracking
()
VERIFIED
FIXED
mozilla0.9.7
People
(Reporter: bbaetz, Assigned: bnesse)
Details
(Whiteboard: [patch])
Attachments
(1 file, 2 obsolete files)
4.04 KB,
patch
|
ccarlen
:
review+
alecf
:
superreview+
|
Details | Diff | Splinter Review |
In working on bug 43567, I've added a new pref and a pref listener. There
was a question on whether I was allowed to do:
rv = prefSrv->GetBranch("network.ftp.", getter_AddRefs(branch));
...
pbi->AddObserver("idleConnectionTimeout", this, PR_TRUE);
and be notified when the network.ftp.idleConnectionTimeout pref changed.
Alecf said yes, but looking at the nsPrefBranch.cpp code, I can't see
where mPrefRoot is used before calling PREF_RegisterCallback.
I did some testing, and if I replace the branch with nsnull, (and observe
"network.ftp.idleConnectionTimeout" instead) then the observer is called.
Interestingly, if I use the code as above (observing the network.ftp branch),
then changing a pref called "idleConnectionTimeout" doesn't appear to fire the
observer either, so either my quick test hacking one of the pref panels wasn't
quite right, or something else is using mPrefRoot correctly, and is getting
confused.
Assignee | ||
Comment 1•23 years ago
|
||
Hmm, I'm pretty sure I had a note to myself somewhere about this exact issue...I
wonder where it went. :(
I expect that mPrefRoot will also need to be removed before calling Observe() to
eliminate confusion on the caller's part...
Reporter | ||
Comment 2•23 years ago
|
||
My Observe method is going to be given a prefbranch as one of the params. I
should be able to expect that passing in the same string to GetFooPref as I did
to AddObserver should work, and that I get back the same pref branch I called
AddObserver on.
Its up to the nsIObserver implementation to avoid ambiguities. I suspect that
those would be rather rare, though.
Assignee | ||
Comment 3•23 years ago
|
||
Comment 4•23 years ago
|
||
well, the one concern I have here is that the OBSERVER needs to get the
prefbranch that they originally passed in, not just the root prefbranch.. is
that happening here? (I've forgotten if the pref branches have their own
observer lists or not)
Assignee | ||
Comment 5•23 years ago
|
||
The only reason this works is because the prefBranch associated with the
callback is stored in the callback structure. :)
The is, however, one gotcha I did notice. Because the prefService keeps a
reference to the default branch you can register an observer, release the
branch, and it works. If you supply a root though, you must retain a reference
to the branch, otherwise the branch is released as soon as it goes out of scope.
Assignee | ||
Comment 6•23 years ago
|
||
bbaetz, do you want to review this?
OS: Linux → All
Hardware: PC → All
Whiteboard: [patch]
Target Milestone: --- → mozilla0.9.7
Reporter | ||
Comment 7•23 years ago
|
||
I'm not in a position to test this now, but:
"If you supply a root though, you must retain a reference
to the branch, otherwise the branch is released as soon as it goes out of scope."
That doesn't sound intuative. Why can't you just addref the branch in the
addobserver call?
Assignee | ||
Comment 8•23 years ago
|
||
Until recently this would have been a really bad idea because it would have
practically guaranteed that no branch objects would ever been released. With the
recent shutdown obeserver changes, this might be safer. I'll have to think on it
a little...
Assignee | ||
Comment 9•23 years ago
|
||
I don't see any potential issues with doing an addref on the "top level" branch
because it will never be released anyway (because it is cached/owned by the pref
service.)
I can see where doing an addref on a non top level branch could cause bloat/leak
situations if the object doing the observing doesn't call RemoveObserver(). When
an object adds itself as an observer it is Addref()'ed. If this object is
subsequently Release()'d, it won't be deleted because the Observer queue still
has a hold on it.
The aHoldWeak parameter was added to get around this. This allows the object to
be deleted, while only retaining a stale reference in the observer list (which
is subsequently removed if a notification to the deleted object is attempted.)
If you add branch ref counting into this situation the (unused) branch will
remain along with the stale object reference. This will remain in memory until a
situation which would trigger notification happens, or until xpcom shutdown.
This might also add some complexities when removing observers as it would need
to insure that the branch deletion is not triggered while it is removing the
observer (due to the observer list having the only branch reference.)
Assignee | ||
Comment 10•23 years ago
|
||
After explaining my, apparently confusing, comments to alecf we came up with a
workable solution for this. I implemented it. It works great. But... I'm not
going to post the revised patch. Here's why...
The main purpose of the additional changes would be to allow a consumer to
create a non top level branch and not keep a reference to it. Unfortunately the
consumer might very well be doing something similar to the code I used for my
test case:
http://lxr.mozilla.org/seamonkey/source/netwerk/cache/src/nsCacheService.cpp
In the Install() method at line 129, the prefservice is grabbed, and a branch
requested from it. The observers are added to this branch, and the branch is
released. In the Remove() method at line 177 this process is repeated to remove
the observers.
The problem is that, unless the prefservice caches the branch, 2 different (new)
branches will be returned. The RemoveObserver calls will fail because there are
no observers on the (newly created) branch.
The right answer is to have the prefservice cache the non top level branch, but
that may have additional issues associated with it.
Assignee | ||
Comment 11•23 years ago
|
||
My recommendation on this would be to check in the current patch to fix the this
bug, and to open a new bug to add caching for non top level branches to the
prefservice.
Reporter | ||
Comment 12•23 years ago
|
||
I was under the impression that doing things using a subbranch was more
efficient, because we didn't have to look up each component in the branch all
the time.
Is this not (currently) the case?
Comment 13•23 years ago
|
||
Comment on attachment 56756 [details] [diff] [review]
Proposed patch.
I agree with bnesse. sr=alecf
bbaetz: it isn't the case right now, but we designed things so that we could do
that in the future..
Attachment #56756 -
Flags: superreview+
Assignee | ||
Comment 14•23 years ago
|
||
Attachment #56756 -
Attachment is obsolete: true
Comment 15•23 years ago
|
||
Comment on attachment 60397 [details] [diff] [review]
A slightly better version without excessive error checking.
can't use static_cast<> - you have to use NS_STATIC_CAST()
also, seems like you're reversing the value of "domain" - I thought domain was
the prefix of a pref, not the suffix?
Assignee | ||
Comment 16•23 years ago
|
||
Changed static_cast to NS_STATIC_CAST. Changed variable name from domain to
suffix. :)
Attachment #60397 -
Attachment is obsolete: true
Comment 17•23 years ago
|
||
Comment on attachment 60405 [details] [diff] [review]
Patch addressing alecf's comments
thanks
sr=alecf
Attachment #60405 -
Flags: superreview+
Comment 18•23 years ago
|
||
Comment on attachment 60405 [details] [diff] [review]
Patch addressing alecf's comments
r=ccarlen
Attachment #60405 -
Flags: review+
Assignee | ||
Comment 19•23 years ago
|
||
Created bug 113635 to address the caching of non-top level branches.
Assignee | ||
Comment 20•23 years ago
|
||
Fix checked in.
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•