Bug 1341374: ensure mtransport refcounting is happening on the same thread
MozReview-Commit-ID: 6Q3Wc1dIfnR
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -202,49 +202,62 @@ public:
nsIThread* GetThread() {
return mThread;
}
/*
* Keep track of how many instances are using a SingletonThreadHolder.
* When no one is using it, shut it down
*/
- MozExternalRefCountType AddUse()
+ void AddUse()
{
- MOZ_ASSERT(mParentThread == NS_GetCurrentThread());
+ RUN_ON_THREAD(mParentThread,
+ mozilla::WrapRunnable(RefPtr<SingletonThreadHolder>(this),
+ &SingletonThreadHolder::AddUse_i),
+ NS_DISPATCH_SYNC);
+ }
+
+ void AddUse_i()
+ {
MOZ_ASSERT(int32_t(mUseCount) >= 0, "illegal refcnt");
nsrefcnt count = ++mUseCount;
if (count == 1) {
// idle -> in-use
nsresult rv = NS_NewNamedThread(mName, getter_AddRefs(mThread));
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv) && mThread,
"Should successfully create mtransport I/O thread");
r_log(LOG_GENERIC,LOG_DEBUG,"Created wrapped SingletonThread %p",
mThread.get());
}
- r_log(LOG_GENERIC,LOG_DEBUG,"AddUse: %lu", (unsigned long) count);
- return count;
+ r_log(LOG_GENERIC,LOG_DEBUG,"AddUse_i: %lu", (unsigned long) count);
}
- MozExternalRefCountType ReleaseUse()
+ void ReleaseUse()
+ {
+ RUN_ON_THREAD(mParentThread,
+ mozilla::WrapRunnable(RefPtr<SingletonThreadHolder>(this),
+ &SingletonThreadHolder::ReleaseUse_i),
+ NS_DISPATCH_SYNC);
+ }
+
+ void ReleaseUse_i()
{
MOZ_ASSERT(mParentThread == NS_GetCurrentThread());
nsrefcnt count = --mUseCount;
MOZ_ASSERT(int32_t(mUseCount) >= 0, "illegal refcnt");
if (count == 0) {
// in-use -> idle -- no one forcing it to remain instantiated
r_log(LOG_GENERIC,LOG_DEBUG,"Shutting down wrapped SingletonThread %p",
mThread.get());
mThread->Shutdown();
mThread = nullptr;
// It'd be nice to use a timer instead... But be careful of
// xpcom-shutdown-threads in that case
}
- r_log(LOG_GENERIC,LOG_DEBUG,"ReleaseUse: %lu", (unsigned long) count);
- return count;
+ r_log(LOG_GENERIC,LOG_DEBUG,"ReleaseUse_i: %lu", (unsigned long) count);
}
private:
nsCString mName;
nsAutoRefCnt mUseCount;
nsCOMPtr<nsIThread> mParentThread;
nsCOMPtr<nsIThread> mThread;
};
@@ -1683,18 +1696,17 @@ NrTcpSocketIpc::NrTcpSocketIpc(nsIThread
NrTcpSocketIpc::~NrTcpSocketIpc()
{
// also guarantees socket_child_ is released from the io_thread
// close(), but transfer the socket_child_ reference to die as well
RUN_ON_THREAD(io_thread_,
mozilla::WrapRunnableNM(&NrTcpSocketIpc::release_child_i,
- socket_child_.forget().take(),
- sts_thread_),
+ socket_child_.forget().take()),
NS_DISPATCH_NORMAL);
}
//
// nsITCPSocketCallback methods
//
NS_IMETHODIMP NrTcpSocketIpc::UpdateReadyState(uint32_t aReadyState) {
NrSocketIpcState temp = NR_INIT;
@@ -1996,18 +2008,17 @@ void NrTcpSocketIpc::close_i() {
if (!socket_child_) {
return;
}
socket_child_->SendClose();
}
// close(), but transfer the socket_child_ reference to die as well
// static
-void NrTcpSocketIpc::release_child_i(dom::TCPSocketChild* aChild,
- nsCOMPtr<nsIEventTarget> sts_thread) {
+void NrTcpSocketIpc::release_child_i(dom::TCPSocketChild* aChild) {
RefPtr<dom::TCPSocketChild> socket_child_ref =
already_AddRefed<dom::TCPSocketChild>(aChild);
if (socket_child_ref) {
socket_child_ref->SendClose();
}
// io_thread_ is MainThread, so no use to release
}
--- a/media/mtransport/nr_socket_prsock.h
+++ b/media/mtransport/nr_socket_prsock.h
@@ -369,17 +369,17 @@ private:
uint16_t remote_port,
const nsACString &local_addr,
uint16_t local_port,
const nsACString &tls_host);
void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf,
uint32_t tracking_number);
void close_i();
- static void release_child_i(dom::TCPSocketChild* aChild, nsCOMPtr<nsIEventTarget> ststhread);
+ static void release_child_i(dom::TCPSocketChild* aChild);
// STS thread executor
void message_sent_s(uint32_t bufferedAmount, uint32_t tracking_number);
void recv_message_s(nr_tcp_message *msg);
void update_state_s(NrSocketIpcState next_state);
void maybe_post_socket_ready();
// Accessed from UpdateReadyState (not sts_thread) to avoid sending