diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-30 06:09:40 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-30 06:09:40 +0000 |
commit | 9328443b6546402da992f1c37ee97d94667a709e (patch) | |
tree | 1531485bbbfa635479652a1eca7df85754251a6c /net/base/network_config_watcher_mac.cc | |
parent | 39b16c2480c50d79459bc79eaf82d51efdd619c1 (diff) | |
download | chromium_src-9328443b6546402da992f1c37ee97d94667a709e.zip chromium_src-9328443b6546402da992f1c37ee97d94667a709e.tar.gz chromium_src-9328443b6546402da992f1c37ee97d94667a709e.tar.bz2 |
Use notification-based API for getting system proxy settings on Mac rather than polling.
BUG=50587
Review URL: http://codereview.chromium.org/3078009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54288 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/network_config_watcher_mac.cc')
-rw-r--r-- | net/base/network_config_watcher_mac.cc | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/net/base/network_config_watcher_mac.cc b/net/base/network_config_watcher_mac.cc new file mode 100644 index 0000000..8767dff --- /dev/null +++ b/net/base/network_config_watcher_mac.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/network_config_watcher_mac.h" + +#include <SystemConfiguration/SCDynamicStoreKey.h> +#include <SystemConfiguration/SCSchemaDefinitions.h> +#include <algorithm> + +#include "base/thread.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 { + +NetworkConfigWatcherMac::NetworkConfigWatcherMac() + : notifier_thread_(new base::Thread("NetworkConfigWatcher")) { + // 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); + // 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(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); +} + +// static +void NetworkConfigWatcherMac::DynamicStoreCallback( + SCDynamicStoreRef /* store */, + CFArrayRef changed_keys, + void* config) { + NetworkConfigWatcherMac* net_config = + static_cast<NetworkConfigWatcherMac*>(config); + net_config->OnNetworkConfigChange(changed_keys); +} + +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()); + + 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()); + + // Add a run loop source for a dynamic store to the current run loop. + SCDynamicStoreContext context = { + 0, // Version 0. + this, // User data. + NULL, // This is not reference counted. No retain function. + NULL, // This is not reference counted. No release function. + NULL, // No description for this. + }; + scoped_cftyperef<SCDynamicStoreRef> store(SCDynamicStoreCreate( + NULL, CFSTR("org.chromium"), DynamicStoreCallback, &context)); + run_loop_source_.reset(SCDynamicStoreCreateRunLoopSource( + NULL, store.get(), 0)); + CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source_.get(), + kCFRunLoopCommonModes); + + // Set up notifications for interface and IP address changes. + SetDynamicStoreNotificationKeys(store.get()); + + MessageLoop::current()->AddDestructionObserver(this); +} + +} // namespace net |