mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1099414: Ensure that NrSocketIpc is destroyed on STS, for consistency. r=ekr
--HG-- extra : rebase_source : e706370706dd0d9ec938798966c752f298a260bf
This commit is contained in:
parent
c66aed798c
commit
98910d890f
@ -693,9 +693,57 @@ abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
// NrSocketIpc Implementation
|
||||
NS_IMPL_ISUPPORTS(NrSocketIpc, nsIUDPSocketInternal)
|
||||
NS_IMPL_ISUPPORTS(NrSocketIpcProxy, 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)
|
||||
: err_(false),
|
||||
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_->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,
|
||||
/* loopback = */ false))) {
|
||||
err_ = true;
|
||||
|
@ -188,8 +188,7 @@ private:
|
||||
DISALLOW_COPY_ASSIGN(nr_udp_message);
|
||||
};
|
||||
|
||||
class NrSocketIpc : public NrSocketBase,
|
||||
public nsIUDPSocketInternal {
|
||||
class NrSocketIpc : public NrSocketBase {
|
||||
public:
|
||||
|
||||
enum NrSocketIpcState {
|
||||
@ -200,8 +199,17 @@ public:
|
||||
NR_CLOSED,
|
||||
};
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIUDPSOCKETINTERNAL
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrSocketIpc)
|
||||
|
||||
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);
|
||||
|
||||
@ -240,6 +248,22 @@ private:
|
||||
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,
|
||||
nr_transport_addr *addr,
|
||||
int protocol);
|
||||
|
@ -96,6 +96,25 @@ RUN_ON_THREAD(nsIEventTarget *thread, detail::runnable_args_base<detail::Returns
|
||||
#define ASSERT_ON_THREAD(t)
|
||||
#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 */
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user