| Index: net/base/network_config_watcher_mac.cc
|
| diff --git a/net/base/network_config_watcher_mac.cc b/net/base/network_config_watcher_mac.cc
|
| index 365859e275e025a78758afb6dabdf45406219d53..dd93067c7d275c397a4c864b0d36812c6affacf3 100644
|
| --- a/net/base/network_config_watcher_mac.cc
|
| +++ b/net/base/network_config_watcher_mac.cc
|
| @@ -8,12 +8,10 @@
|
| #include <SystemConfiguration/SCSchemaDefinitions.h>
|
| #include <algorithm>
|
|
|
| +#include "base/compiler_specific.h"
|
| #include "base/thread.h"
|
| #include "base/mac/scoped_cftyperef.h"
|
|
|
| -// We only post tasks to a child thread we own, so we don't need refcounting.
|
| -DISABLE_RUNNABLE_METHOD_REFCOUNT(net::NetworkConfigWatcherMac);
|
| -
|
| namespace net {
|
|
|
| namespace {
|
| @@ -27,48 +25,59 @@ void DynamicStoreCallback(SCDynamicStoreRef /* store */,
|
| net_config_delegate->OnNetworkConfigChange(changed_keys);
|
| }
|
|
|
| -} // namespace
|
| +class NetworkConfigWatcherMacThread : public base::Thread {
|
| + public:
|
| + NetworkConfigWatcherMacThread(NetworkConfigWatcherMac::Delegate* delegate);
|
| + virtual ~NetworkConfigWatcherMacThread();
|
|
|
| -NetworkConfigWatcherMac::NetworkConfigWatcherMac(
|
| - Delegate* delegate)
|
| - : notifier_thread_(new base::Thread("NetworkConfigWatcher")),
|
| - delegate_(delegate) {
|
| - // We create this notifier thread because the notification implementation
|
| - // needs a thread with a CFRunLoop, and there's no guarantee that
|
| - // MessageLoop::current() meets that criterion.
|
| - base::Thread::Options thread_options(MessageLoop::TYPE_UI, 0);
|
| - notifier_thread_->StartWithOptions(thread_options);
|
| + protected:
|
| + // base::Thread
|
| + virtual void Init();
|
| + virtual void CleanUp();
|
| +
|
| + private:
|
| + // The SystemConfiguration calls in this function can lead to contention early
|
| + // on, so we invoke this function later on in startup to keep it fast.
|
| + void InitNotifications();
|
| +
|
| + base::mac::ScopedCFTypeRef<CFRunLoopSourceRef> run_loop_source_;
|
| + NetworkConfigWatcherMac::Delegate* const delegate_;
|
| + ScopedRunnableMethodFactory<NetworkConfigWatcherMacThread> method_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(NetworkConfigWatcherMacThread);
|
| +};
|
| +
|
| +NetworkConfigWatcherMacThread::NetworkConfigWatcherMacThread(
|
| + NetworkConfigWatcherMac::Delegate* delegate)
|
| + : base::Thread("NetworkConfigWatcher"),
|
| + delegate_(delegate),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {}
|
| +
|
| +NetworkConfigWatcherMacThread::~NetworkConfigWatcherMacThread() {
|
| + Stop();
|
| +}
|
| +
|
| +void NetworkConfigWatcherMacThread::Init() {
|
| // TODO(willchan): Look to see if there's a better signal for when it's ok to
|
| // initialize this, rather than just delaying it by a fixed time.
|
| - const int kNotifierThreadInitializationDelayMS = 1000;
|
| - notifier_thread_->message_loop()->PostDelayedTask(
|
| + const int kInitializationDelayMS = 1000;
|
| + message_loop()->PostDelayedTask(
|
| FROM_HERE,
|
| - NewRunnableMethod(this, &NetworkConfigWatcherMac::Init),
|
| - kNotifierThreadInitializationDelayMS);
|
| -}
|
| -
|
| -NetworkConfigWatcherMac::~NetworkConfigWatcherMac() {
|
| - // We don't need to explicitly Stop(), but doing so allows us to sanity-
|
| - // check that the notifier thread shut down properly.
|
| - notifier_thread_->Stop();
|
| - DCHECK(run_loop_source_ == NULL);
|
| + method_factory_.NewRunnableMethod(
|
| + &NetworkConfigWatcherMacThread::InitNotifications),
|
| + kInitializationDelayMS);
|
| }
|
|
|
| -void NetworkConfigWatcherMac::WillDestroyCurrentMessageLoop() {
|
| - DCHECK(notifier_thread_ != NULL);
|
| - // We can't check the notifier_thread_'s message_loop(), as it's now 0.
|
| - // DCHECK_EQ(notifier_thread_->message_loop(), MessageLoop::current());
|
| +void NetworkConfigWatcherMacThread::CleanUp() {
|
| + if (!run_loop_source_.get())
|
| + return;
|
|
|
| - DCHECK(run_loop_source_ != NULL);
|
| CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_source_.get(),
|
| kCFRunLoopCommonModes);
|
| run_loop_source_.reset();
|
| }
|
|
|
| -void NetworkConfigWatcherMac::Init() {
|
| - DCHECK(notifier_thread_ != NULL);
|
| - DCHECK_EQ(notifier_thread_->message_loop(), MessageLoop::current());
|
| -
|
| +void NetworkConfigWatcherMacThread::InitNotifications() {
|
| // Add a run loop source for a dynamic store to the current run loop.
|
| SCDynamicStoreContext context = {
|
| 0, // Version 0.
|
| @@ -86,8 +95,19 @@ void NetworkConfigWatcherMac::Init() {
|
|
|
| // Set up notifications for interface and IP address changes.
|
| delegate_->SetDynamicStoreNotificationKeys(store.get());
|
| +}
|
| +
|
| +} // namespace
|
|
|
| - MessageLoop::current()->AddDestructionObserver(this);
|
| +NetworkConfigWatcherMac::NetworkConfigWatcherMac(Delegate* delegate)
|
| + : notifier_thread_(new NetworkConfigWatcherMacThread(delegate)) {
|
| + // We create this notifier thread because the notification implementation
|
| + // needs a thread with a CFRunLoop, and there's no guarantee that
|
| + // MessageLoop::current() meets that criterion.
|
| + base::Thread::Options thread_options(MessageLoop::TYPE_UI, 0);
|
| + notifier_thread_->StartWithOptions(thread_options);
|
| }
|
|
|
| +NetworkConfigWatcherMac::~NetworkConfigWatcherMac() {}
|
| +
|
| } // namespace net
|
|
|