Bug 1099414 - Ensure that NrSocketIpc is destroyed on STS, for consistency. r=ekr

This commit is contained in:
Byron Campen [:bwc] 2014-12-23 16:22:02 -08:00
Родитель febbdc0fe9
Коммит d69a42aa34
3 изменённых файлов: 106 добавлений и 7 удалений

Просмотреть файл

@ -693,9 +693,57 @@ abort:
return(_status); return(_status);
} }
// NrSocketIpc Implementation NS_IMPL_ISUPPORTS(NrSocketIpcProxy, nsIUDPSocketInternal)
NS_IMPL_ISUPPORTS(NrSocketIpc, nsIUDPSocketInternal)
nsresult
NrSocketIpcProxy::Init(const nsRefPtr<NrSocketIpc>& socket)
{
nsresult rv;
sts_thread_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Failed to get STS thread");
return rv;
}
socket_ = socket;
return NS_OK;
}
NrSocketIpcProxy::~NrSocketIpcProxy()
{
// Send our ref to STS to be released
RUN_ON_THREAD(sts_thread_,
mozilla::WrapRelease(socket_.forget()),
NS_DISPATCH_NORMAL);
}
// IUDPSocketInternal interfaces
// callback while error happened in UDP socket operation
NS_IMETHODIMP NrSocketIpcProxy::CallListenerError(const nsACString &message,
const nsACString &filename,
uint32_t line_number) {
return socket_->CallListenerError(message, filename, line_number);
}
// callback while receiving UDP packet
NS_IMETHODIMP NrSocketIpcProxy::CallListenerReceivedData(const nsACString &host,
uint16_t port,
const uint8_t *data,
uint32_t data_length) {
return socket_->CallListenerReceivedData(host, port, data, data_length);
}
// callback while UDP socket is opened
NS_IMETHODIMP NrSocketIpcProxy::CallListenerOpened() {
return socket_->CallListenerOpened();
}
// callback while UDP socket is closed
NS_IMETHODIMP NrSocketIpcProxy::CallListenerClosed() {
return socket_->CallListenerClosed();
}
// NrSocketIpc Implementation
NrSocketIpc::NrSocketIpc(const nsCOMPtr<nsIEventTarget> &main_thread) NrSocketIpc::NrSocketIpc(const nsCOMPtr<nsIEventTarget> &main_thread)
: err_(false), : err_(false),
state_(NR_INIT), state_(NR_INIT),
@ -1022,7 +1070,15 @@ void NrSocketIpc::create_m(const nsACString &host, const uint16_t port) {
socket_child_ = new nsMainThreadPtrHolder<nsIUDPSocketChild>(socketChild); socket_child_ = new nsMainThreadPtrHolder<nsIUDPSocketChild>(socketChild);
socket_child_->SetFilterName(nsCString("stun")); socket_child_->SetFilterName(nsCString("stun"));
if (NS_FAILED(socket_child_->Bind(this, host, port, nsRefPtr<NrSocketIpcProxy> proxy(new NrSocketIpcProxy);
rv = proxy->Init(this);
if (NS_FAILED(rv)) {
err_ = true;
mon.NotifyAll();
return;
}
if (NS_FAILED(socket_child_->Bind(proxy, host, port,
/* reuse = */ false, /* reuse = */ false,
/* loopback = */ false))) { /* loopback = */ false))) {
err_ = true; err_ = true;

Просмотреть файл

@ -188,8 +188,7 @@ private:
DISALLOW_COPY_ASSIGN(nr_udp_message); DISALLOW_COPY_ASSIGN(nr_udp_message);
}; };
class NrSocketIpc : public NrSocketBase, class NrSocketIpc : public NrSocketBase {
public nsIUDPSocketInternal {
public: public:
enum NrSocketIpcState { enum NrSocketIpcState {
@ -200,8 +199,17 @@ public:
NR_CLOSED, NR_CLOSED,
}; };
NS_DECL_THREADSAFE_ISUPPORTS NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrSocketIpc)
NS_DECL_NSIUDPSOCKETINTERNAL
NS_IMETHODIMP CallListenerError(const nsACString &message,
const nsACString &filename,
uint32_t line_number);
NS_IMETHODIMP CallListenerReceivedData(const nsACString &host,
uint16_t port,
const uint8_t *data,
uint32_t data_length);
NS_IMETHODIMP CallListenerOpened();
NS_IMETHODIMP CallListenerClosed();
explicit NrSocketIpc(const nsCOMPtr<nsIEventTarget> &main_thread); explicit NrSocketIpc(const nsCOMPtr<nsIEventTarget> &main_thread);
@ -240,6 +248,22 @@ private:
ReentrantMonitor monitor_; ReentrantMonitor monitor_;
}; };
// The socket child holds onto one of these, which just passes callbacks
// through and makes sure the ref to the NrSocketIpc is released on STS.
class NrSocketIpcProxy : public nsIUDPSocketInternal {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIUDPSOCKETINTERNAL
nsresult Init(const nsRefPtr<NrSocketIpc>& socket);
private:
virtual ~NrSocketIpcProxy();
nsRefPtr<NrSocketIpc> socket_;
nsCOMPtr<nsIEventTarget> sts_thread_;
};
int nr_netaddr_to_transport_addr(const net::NetAddr *netaddr, int nr_netaddr_to_transport_addr(const net::NetAddr *netaddr,
nr_transport_addr *addr, nr_transport_addr *addr,
int protocol); int protocol);

Просмотреть файл

@ -96,6 +96,25 @@ RUN_ON_THREAD(nsIEventTarget *thread, detail::runnable_args_base<detail::Returns
#define ASSERT_ON_THREAD(t) #define ASSERT_ON_THREAD(t)
#endif #endif
template <class T>
class DispatchedRelease : public detail::runnable_args_base<detail::NoResult> {
public:
explicit DispatchedRelease(already_AddRefed<T>& ref) : ref_(ref) {}
NS_IMETHOD Run() {
ref_ = nullptr;
return NS_OK;
}
private:
nsRefPtr<T> ref_;
};
template <typename T>
DispatchedRelease<T>* WrapRelease(already_AddRefed<T>&& ref)
{
return new DispatchedRelease<T>(ref);
}
} /* namespace mozilla */ } /* namespace mozilla */
#endif #endif