#include "base/lazy_instance.h"
#include "chrome/common/local_discovery/local_discovery_messages.h"
-#include "chrome/utility/local_discovery/service_discovery_client_impl.h"
+#include "chrome/common/local_discovery/service_discovery_client_impl.h"
#include "content/public/utility/utility_thread.h"
#include "net/socket/socket_descriptor.h"
#include "net/udp/datagram_server_socket.h"
net::PlatformSocketFactory::SetInstance(this);
}
- virtual ~ScopedSocketFactory() {
+ ~ScopedSocketFactory() override {
net::PlatformSocketFactory::SetInstance(NULL);
ClosePlatformSocket(socket_);
socket_ = net::kInvalidSocket;
}
- virtual net::SocketDescriptor CreateSocket(int family, int type,
- int protocol) OVERRIDE {
+ net::SocketDescriptor CreateSocket(int family,
+ int type,
+ int protocol) override {
DCHECK_EQ(type, SOCK_DGRAM);
DCHECK(family == AF_INET || family == AF_INET6);
net::SocketDescriptor result = net::kInvalidSocket;
class PreCreatedMDnsSocketFactory : public net::MDnsSocketFactory {
public:
PreCreatedMDnsSocketFactory() {}
- virtual ~PreCreatedMDnsSocketFactory() {
- Reset();
+ ~PreCreatedMDnsSocketFactory() override {
+ // Not empty if process exits too fast, before starting mDns code. If
+ // happened, destructors may crash accessing destroyed global objects.
+ sockets_.weak_clear();
}
// net::MDnsSocketFactory implementation:
- virtual void CreateSockets(
- ScopedVector<net::DatagramServerSocket>* sockets) OVERRIDE {
- for (size_t i = 0; i < sockets_.size(); ++i) {
- // Takes ownership of sockets_[i].socket;
- ScopedSocketFactory platform_factory(sockets_[i].socket);
- scoped_ptr<net::DatagramServerSocket> socket(
- net::CreateAndBindMDnsSocket(sockets_[i].address_family,
- sockets_[i].interface_index));
- if (socket)
- sockets->push_back(socket.release());
- }
- sockets_.clear();
+ void CreateSockets(
+ ScopedVector<net::DatagramServerSocket>* sockets) override {
+ sockets->swap(sockets_);
+ Reset();
}
- void AddSocket(const SocketInfo& socket) {
- sockets_.push_back(socket);
+ void AddSocket(const SocketInfo& socket_info) {
+ // Takes ownership of socket_info.socket;
+ ScopedSocketFactory platform_factory(socket_info.socket);
+ scoped_ptr<net::DatagramServerSocket> socket(
+ net::CreateAndBindMDnsSocket(socket_info.address_family,
+ socket_info.interface_index));
+ if (socket) {
+ socket->DetachFromThread();
+ sockets_.push_back(socket.release());
+ }
}
void Reset() {
- for (size_t i = 0; i < sockets_.size(); ++i) {
- if (sockets_[i].socket != net::kInvalidSocket)
- ClosePlatformSocket(sockets_[i].socket);
- }
sockets_.clear();
}
private:
- std::vector<SocketInfo> sockets_;
+ ScopedVector<net::DatagramServerSocket> sockets_;
DISALLOW_COPY_AND_ASSIGN(PreCreatedMDnsSocketFactory);
};
}
bool ServiceDiscoveryMessageHandler::InitializeThread() {
- if (discovery_task_runner_)
+ if (discovery_task_runner_.get())
return true;
if (discovery_thread_)
return false;
base::Bind(&ServiceDiscoveryMessageHandler::InitializeMdns,
base::Unretained(this)));
}
- return discovery_task_runner_ != NULL;
+ return discovery_task_runner_.get() != NULL;
}
bool ServiceDiscoveryMessageHandler::OnMessageReceived(
}
void ServiceDiscoveryMessageHandler::ShutdownLocalDiscovery() {
- if (!discovery_task_runner_)
+ if (!discovery_task_runner_.get())
return;
discovery_task_runner_->PostTask(