зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1099414 - Ensure that NrSocketIpc is destroyed on STS, for consistency. r=ekr
This commit is contained in:
Родитель
febbdc0fe9
Коммит
d69a42aa34
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче