Closed Bug 174131 Opened 22 years ago Closed 22 years ago

shutdown leak: nsHttpHandler and nsHttpConnection objects

Categories

(Core :: Networking: HTTP, defect, P2)

x86
Linux
defect

Tracking

()

VERIFIED FIXED
mozilla1.3alpha

People

(Reporter: dbaron, Assigned: dbaron)

Details

(Keywords: memory-leak, Whiteboard: [patch])

Attachments

(1 file, 2 obsolete files)

nsHttpHandler and nsHttpConnection objects have a circular ownership model (ugh!). The nsHttpHandler owns a reference to all connections in its arrays mActiveConnections and mIdleConnections. The connections all own a reference to the nsHttpHandler (added in the connection's constructor and released in the connection's destructor). This means that the code, in the nsHttpHandler destructor, to call DropConnections to release the connections never gets called because the destructor won't get called until the connections are released. I'll attach a patch that calls DropConnections from the XPCOM shutdown observer as well (but leaves in the calls in the destructor, although perhaps they should be removed and replaced with an assertion that the arrays are empty). It also fixes what looks to me like a logic error in nsHttpHandler::PurgeDeadConnections.
Status: NEW → ASSIGNED
Keywords: mlk
Priority: -- → P2
Target Milestone: --- → mozilla1.3alpha
Comment on attachment 102683 [details] [diff] [review] patch it was my fix for bug 143821 that introduced this cycle. still, i would have expected the "profile-before-change" and/or "session-logout" events to sufficiently break this ownership cycle. >Index: nsHttpHandler.cpp >- nsHttpConnection *conn = (nsHttpConnection *) mIdleConnections[i]; >+ nsHttpConnection *conn = NS_STATIC_CAST(nsHttpConnection *, >+ mIdleConnections[i]); does this really help? the linebreak seems to hurt readability more than the STATIC_CAST helps IMO :( > NS_RELEASE(conn); >+ --i; > } thanks for catching this! how about removing the ++i from the |for| statement and adding a |else ++i;| instead? might also be good to iterate over this list backwards to minimize the cost of remove, but whatever ;-) otherwise, sr=darin
Attachment #102683 - Flags: superreview+
oh, and i agree.. the calls to DropConnections in ~nsHttpHandler don't make any sense. they should be removed and replaced with an assertion.
Comment on attachment 102683 [details] [diff] [review] patch What darin said (although I don't mind with --i, personally) r=bbaetz either way
Attachment #102683 - Flags: review+
Attached patch patch (obsolete) — Splinter Review
I think this addresses all the comments. However, a few more notes / comments / questions: Darin's comment about iterating through the array backwards made me realize that when going backwards, there's no need to monkey with the index, so I did that instead. I put a printf in nsHttpHandler::Observe, and the only notification I got in the entire run of Mozilla was "xpcom-shutdown". Is that bad? Should the code I moved from the destructor to nsHttpHandler::Observe need to hold mConnectionLock, since it's no longer in the destructor?
Attachment #102683 - Attachment is obsolete: true
Oh, and I just changed the RemoveElement(conn) to RemoveElementAt(i), which doesn't need to search the array (making the whole thing an O(N^2) algorithm!) in my tree, but I'm not going to bother attaching a new patch for just that (unless I need no further changes).
cc'ing kaie since your observation may explain the NSS shutdown problem he fixed by moving DropConnections to the network-teardown event.
Comment on attachment 102746 [details] [diff] [review] patch >Index: nsHttpHandler.cpp >+ LOG(("dropping active connections...\n")); >+ DropConnections(mActiveConnections); >+ >+ LOG(("dropping idle connections...\n")); >+ DropConnections(mIdleConnections); yup, this does need to be protected by mConnectionLock. it is very possible for connections to access the http handler from the socket thread. i can't believe i forgot about that!! { nsAutoLock lock(mConnectionLock); ... DropConnections(...); } sr=darin w/ that and the RemoveElementAt change. thx :)
Attachment #102746 - Flags: superreview+
Attached patch patchSplinter Review
The changes from attachment 102746 [details] [diff] [review] are: * locking, per comment 8 (and comment 5) * RemoveElementAt, per comment 6
Attachment #102746 - Attachment is obsolete: true
Comment on attachment 102793 [details] [diff] [review] patch Transferring r and sr.
Attachment #102793 - Flags: superreview+
Attachment #102793 - Flags: review+
Wouldn't it make more sense for DropConnections to grab the lock itsself, now that all the callers explicitly grab the lock first? There arne't any reentrency issues with the lock, are there?
no, i think this is better because we want to call DropConnections twice, once for the idle connections and once for the active connections. if we enter and leave the lock between, we could end up missing some connections. this is unlikely in practice because all the pending transactions should be canceled by this point, but it would be a hidden dependency if we didn't do it this way.
Fix checked in to trunk, 2002-11-06 05:01 PDT.
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Will this be included in the 1.2 branch?
marking verified - confirmed patch checked in on trunk
Status: RESOLVED → VERIFIED
QA Contact: httpqa → tever
this patch appears to have caused a shutdown crash. see bug 179391.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: