Closed Bug 807929 Opened 12 years ago Closed 12 years ago

DataChannel object needs to be refcounted - hard to manage the lifetime during deferring close

Categories

(Core :: WebRTC: Networking, defect)

defect
Not set
major

Tracking

()

VERIFIED FIXED
mozilla19
Tracking Status
firefox18 --- affected
firefox19 --- fixed

People

(Reporter: jesup, Assigned: jesup)

References

Details

(Keywords: crash)

Attachments

(2 files, 1 obsolete file)

The raw pointers to DataChannels in the mStreamsOut and mStreamsIn arrays, and ::Close queuing the actual close to be handled by resetting the stream caused a lifetime problem for DataChannel. Also a known problem was managing the lifetime during a runnable. Switching to a refcounted (threadsafe!) impl fixes most of these things. Some fancy footwork is required because nsDeque isn't a template library, so it's hard to store already_AddRefed<> objects in it directly. Note that this means a number of things like NS_NewDOMDataChannel take already_AddRefed<DataChannel>'s, etc.
Attached patch Make DataChannel refcounted (obsolete) — Splinter Review
Attachment #677700 - Flags: review?(mcmanus)
This was crashing in shutdown in Ted's testcase from Bug 807647 once the patch there is applied
Keywords: crash
Target Milestone: --- → mozilla19
Comment on attachment 677700 [details] [diff] [review] Make DataChannel refcounted Review of attachment 677700 [details] [diff] [review]: ----------------------------------------------------------------- I like the ref counts and anything that gets rid of nsAutoPtr I generally approve of. (I dislike the syntax where a = b ends up modifying b.. ) but you've got more uses of already_addrefed in here than I've ever seen.. maybe its just a style thing but I think this would be a lot more reliable if you could get rid of them. I understand you need it for deque, but that can be much more limited, yes? ::: media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ +660,5 @@ > NS_ENSURE_TRUE(dataChannel,NS_ERROR_FAILURE); > > CSFLogDebugS(logTag, __FUNCTION__ << ": making DOMDataChannel"); > > + return NS_NewDOMDataChannel(dataChannel.forget(), mWindow, aRetval); here is a good example.. you are forgetting a reference just to get an already addref'd pointer that gets assigned to a refptr inside DOMDataChannel. why not just pass in dataChannel in this function as a plain DataChannel * in the dom datachannel prototypes which then gets assigned (this time adding a reference) to a refptr. The dataChannel on this stack will soon go out of scope and drop the corresponding reference so they'll still balance. that's the normal pattern afaik. ::: netwerk/sctp/datachannel/DataChannel.cpp @@ +972,3 @@ > channel->mFlags |= DATA_CHANNEL_FLAGS_FINISH_RSP; > + channel->AddRef(); > + mPending.Push(channel); // Can't cast away already_AddRefed<> from channel.forget() DataChannel *tmp = channel.get(); channel.forget(); mPending.Push(tmp); ??
Attachment #677700 - Flags: review?(mcmanus)
(In reply to Patrick McManus [:mcmanus] from comment #3) > Comment on attachment 677700 [details] [diff] [review] > Make DataChannel refcounted > > Review of attachment 677700 [details] [diff] [review]: > ----------------------------------------------------------------- > > I like the ref counts and anything that gets rid of nsAutoPtr I generally > approve of. (I dislike the syntax where a = b ends up modifying b.. ) > > but you've got more uses of already_addrefed in here than I've ever seen.. > maybe its just a style thing but I think this would be a lot more reliable > if you could get rid of them. I understand you need it for deque, but that > can be much more limited, yes? I also need (ok, it saves add/release cycles) to use them in ::Open() and in HandleOpenRequest(). These need to be internally asynchronous (::Open and ::OpenFinish), and so need to keep references. Since they end up holding a reference, and are "giving it up" in returning it, .forget() makes sense, which means already_AddRefed<> (or equivalent; there are several pseudo-synonyms). I think the API chosen for a lot of things in the tree does something similar, but ends up using getter_AddRefs(). I'll comb through an eliminate ones I can. > ::: media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp > @@ +660,5 @@ > > NS_ENSURE_TRUE(dataChannel,NS_ERROR_FAILURE); > > > > CSFLogDebugS(logTag, __FUNCTION__ << ": making DOMDataChannel"); > > > > + return NS_NewDOMDataChannel(dataChannel.forget(), mWindow, aRetval); > > here is a good example.. you are forgetting a reference just to get an > already addref'd pointer that gets assigned to a refptr inside > DOMDataChannel. That one is ::Open - it has to have a reference, and then return it and give it up without having it destroyed. I could return it as a raw pointer from a .forget(), but that's just losing the compiler checking things for me. > ::: netwerk/sctp/datachannel/DataChannel.cpp > @@ +972,3 @@ > > channel->mFlags |= DATA_CHANNEL_FLAGS_FINISH_RSP; > > + channel->AddRef(); > > + mPending.Push(channel); // Can't cast away already_AddRefed<> from channel.forget() > > DataChannel *tmp = channel.get(); > channel.forget(); > mPending.Push(tmp); > ?? Ah, yes, that avoids the add/release pair, thanks. Fought with the compiler for a while there with casts and basically gave up.
Attachment #677700 - Attachment is obsolete: true
Comment on attachment 677784 [details] [diff] [review] Make DataChannel refcounted https://bug807929.bugzilla.mozilla.org/attachment.cgi?id=677783 has the delta between this patch and the last. Reviewing it, all the already_AddRefed<> uses were either ::Open/OpenFinish or ::HandleOpenRequest/Finish, which per before need a ref internally, and the nsDeque stuff. One of the nsDeque AddRef()s is still needed (we need to add it to a deque and return an already_AddRefed<> pointer) I'm open to a different pattern, but this was what worked with the code paths without a redesign (and I'm not sure that would help anyways).
Attachment #677784 - Flags: review?(mcmanus)
Attachment #677784 - Flags: review?(mcmanus) → review+
Status: NEW → RESOLVED
Closed: 12 years ago
Flags: in-testsuite-
Resolution: --- → FIXED
Keywords: verifyme
Depends on: 812275
Verified through testing the other bug.
Status: RESOLVED → VERIFIED
Keywords: verifyme
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: