Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: net/proxy/proxy_config_service_linux.cc

Issue 2872863003: Use base::FileDescriptorWatcher instead of MessageLoopForIO::WatchFileDescriptor in proxy_config_se… (Closed)
Patch Set: fix compile Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/proxy/proxy_config_service_linux.h" 5 #include "net/proxy/proxy_config_service_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #if defined(USE_GCONF) 8 #if defined(USE_GCONF)
9 #include <gconf/gconf-client.h> 9 #include <gconf/gconf-client.h>
10 #endif // defined(USE_GCONF) 10 #endif // defined(USE_GCONF)
11 #include <limits.h> 11 #include <limits.h>
12 #include <stdio.h> 12 #include <stdio.h>
13 #include <stdlib.h> 13 #include <stdlib.h>
14 #include <sys/inotify.h> 14 #include <sys/inotify.h>
15 #include <unistd.h> 15 #include <unistd.h>
16 16
17 #include <map> 17 #include <map>
18 #include <utility> 18 #include <utility>
19 19
20 #include "base/bind.h" 20 #include "base/bind.h"
21 #include "base/compiler_specific.h" 21 #include "base/compiler_specific.h"
22 #include "base/debug/leak_annotations.h" 22 #include "base/debug/leak_annotations.h"
23 #include "base/files/file_descriptor_watcher_posix.h"
23 #include "base/files/file_path.h" 24 #include "base/files/file_path.h"
24 #include "base/files/file_util.h" 25 #include "base/files/file_util.h"
25 #include "base/files/scoped_file.h" 26 #include "base/files/scoped_file.h"
26 #include "base/logging.h" 27 #include "base/logging.h"
27 #include "base/macros.h" 28 #include "base/macros.h"
28 #include "base/message_loop/message_loop.h"
29 #include "base/nix/xdg_util.h" 29 #include "base/nix/xdg_util.h"
30 #include "base/single_thread_task_runner.h" 30 #include "base/single_thread_task_runner.h"
31 #include "base/strings/string_number_conversions.h" 31 #include "base/strings/string_number_conversions.h"
32 #include "base/strings/string_tokenizer.h" 32 #include "base/strings/string_tokenizer.h"
33 #include "base/strings/string_util.h" 33 #include "base/strings/string_util.h"
34 #include "base/threading/thread_restrictions.h" 34 #include "base/threading/thread_restrictions.h"
35 #include "base/timer/timer.h" 35 #include "base/timer/timer.h"
36 #include "net/base/net_errors.h" 36 #include "net/base/net_errors.h"
37 #include "net/http/http_util.h" 37 #include "net/http/http_util.h"
38 #include "net/proxy/proxy_config.h" 38 #include "net/proxy/proxy_config.h"
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 } 851 }
852 852
853 VLOG(1) << "All gsettings tests OK. Will get proxy config from gsettings."; 853 VLOG(1) << "All gsettings tests OK. Will get proxy config from gsettings.";
854 return true; 854 return true;
855 } 855 }
856 #endif // defined(USE_GIO) 856 #endif // defined(USE_GIO)
857 857
858 // This is the KDE version that reads kioslaverc and simulates gconf. 858 // This is the KDE version that reads kioslaverc and simulates gconf.
859 // Doing this allows the main Delegate code, as well as the unit tests 859 // Doing this allows the main Delegate code, as well as the unit tests
860 // for it, to stay the same - and the settings map fairly well besides. 860 // for it, to stay the same - and the settings map fairly well besides.
861 class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter, 861 class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter {
862 public base::MessagePumpLibevent::Watcher {
863 public: 862 public:
864 explicit SettingGetterImplKDE(base::Environment* env_var_getter) 863 explicit SettingGetterImplKDE(base::Environment* env_var_getter)
865 : inotify_fd_(-1), 864 : inotify_fd_(-1),
866 inotify_watcher_(FROM_HERE),
867 notify_delegate_(nullptr), 865 notify_delegate_(nullptr),
868 debounce_timer_(new base::OneShotTimer()), 866 debounce_timer_(new base::OneShotTimer()),
869 indirect_manual_(false), 867 indirect_manual_(false),
870 auto_no_pac_(false), 868 auto_no_pac_(false),
871 reversed_bypass_list_(false), 869 reversed_bypass_list_(false),
872 env_var_getter_(env_var_getter), 870 env_var_getter_(env_var_getter),
873 file_task_runner_(nullptr) { 871 file_task_runner_(nullptr) {
874 // This has to be called on the UI thread (http://crbug.com/69057). 872 // This has to be called on the UI thread (http://crbug.com/69057).
875 base::ThreadRestrictions::ScopedAllowIO allow_io; 873 base::ThreadRestrictions::ScopedAllowIO allow_io;
876 874
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 // The initial read is done on the current thread, not 962 // The initial read is done on the current thread, not
965 // |file_task_runner_|, since we will need to have it for 963 // |file_task_runner_|, since we will need to have it for
966 // SetUpAndFetchInitialConfig(). 964 // SetUpAndFetchInitialConfig().
967 UpdateCachedSettings(); 965 UpdateCachedSettings();
968 return true; 966 return true;
969 } 967 }
970 968
971 void ShutDown() override { 969 void ShutDown() override {
972 if (inotify_fd_ >= 0) { 970 if (inotify_fd_ >= 0) {
973 ResetCachedSettings(); 971 ResetCachedSettings();
974 inotify_watcher_.StopWatchingFileDescriptor(); 972 inotify_watcher_.reset();
975 close(inotify_fd_); 973 close(inotify_fd_);
976 inotify_fd_ = -1; 974 inotify_fd_ = -1;
977 } 975 }
978 debounce_timer_.reset(); 976 debounce_timer_.reset();
979 } 977 }
980 978
981 bool SetUpNotifications( 979 bool SetUpNotifications(
982 ProxyConfigServiceLinux::Delegate* delegate) override { 980 ProxyConfigServiceLinux::Delegate* delegate) override {
983 DCHECK_GE(inotify_fd_, 0); 981 DCHECK_GE(inotify_fd_, 0);
984 DCHECK(file_task_runner_->BelongsToCurrentThread()); 982 DCHECK(file_task_runner_->BelongsToCurrentThread());
985 // We can't just watch the kioslaverc file directly, since KDE will write 983 // We can't just watch the kioslaverc file directly, since KDE will write
986 // a new copy of it and then rename it whenever settings are changed and 984 // a new copy of it and then rename it whenever settings are changed and
987 // inotify watches inodes (so we'll be watching the old deleted file after 985 // inotify watches inodes (so we'll be watching the old deleted file after
988 // the first change, and it will never change again). So, we watch the 986 // the first change, and it will never change again). So, we watch the
989 // directory instead. We then act only on changes to the kioslaverc entry. 987 // directory instead. We then act only on changes to the kioslaverc entry.
990 if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(), 988 if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(),
991 IN_MODIFY | IN_MOVED_TO) < 0) { 989 IN_MODIFY | IN_MOVED_TO) < 0) {
992 return false; 990 return false;
993 } 991 }
994 notify_delegate_ = delegate; 992 notify_delegate_ = delegate;
995 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 993 inotify_watcher_ = base::FileDescriptorWatcher::WatchReadable(
996 inotify_fd_, true, base::MessageLoopForIO::WATCH_READ, 994 inotify_fd_, base::Bind(&SettingGetterImplKDE::OnChangeNotification,
997 &inotify_watcher_, this)) { 995 base::Unretained(this)));
998 return false;
999 }
1000 // Simulate a change to avoid possibly losing updates before this point. 996 // Simulate a change to avoid possibly losing updates before this point.
1001 OnChangeNotification(); 997 OnChangeNotification();
1002 return true; 998 return true;
1003 } 999 }
1004 1000
1005 const scoped_refptr<base::SingleThreadTaskRunner>& GetNotificationTaskRunner() 1001 const scoped_refptr<base::SingleThreadTaskRunner>& GetNotificationTaskRunner()
1006 override { 1002 override {
1007 return file_task_runner_; 1003 return file_task_runner_;
1008 } 1004 }
1009 1005
1010 // Implement base::MessagePumpLibevent::Watcher.
1011 void OnFileCanReadWithoutBlocking(int fd) override {
1012 DCHECK_EQ(fd, inotify_fd_);
1013 DCHECK(file_task_runner_->BelongsToCurrentThread());
1014 OnChangeNotification();
1015 }
1016 void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }
1017
1018 ProxyConfigSource GetConfigSource() override { 1006 ProxyConfigSource GetConfigSource() override {
1019 return PROXY_CONFIG_SOURCE_KDE; 1007 return PROXY_CONFIG_SOURCE_KDE;
1020 } 1008 }
1021 1009
1022 bool GetString(StringSetting key, std::string* result) override { 1010 bool GetString(StringSetting key, std::string* result) override {
1023 string_map_type::iterator it = string_table_.find(key); 1011 string_map_type::iterator it = string_table_.find(key);
1024 if (it == string_table_.end()) 1012 if (it == string_table_.end())
1025 return false; 1013 return false;
1026 *result = it->second; 1014 *result = it->second;
1027 return true; 1015 return true;
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 // new behavior (EINVAL) so we can reuse the code below. 1298 // new behavior (EINVAL) so we can reuse the code below.
1311 errno = EINVAL; 1299 errno = EINVAL;
1312 if (errno != EAGAIN) { 1300 if (errno != EAGAIN) {
1313 PLOG(WARNING) << "error reading inotify file descriptor"; 1301 PLOG(WARNING) << "error reading inotify file descriptor";
1314 if (errno == EINVAL) { 1302 if (errno == EINVAL) {
1315 // Our buffer is not large enough to read the next event. This should 1303 // Our buffer is not large enough to read the next event. This should
1316 // not happen (because its size is calculated to always be sufficiently 1304 // not happen (because its size is calculated to always be sufficiently
1317 // large), but if it does we'd warn continuously since |inotify_fd_| 1305 // large), but if it does we'd warn continuously since |inotify_fd_|
1318 // would be forever ready to read. Close it and stop watching instead. 1306 // would be forever ready to read. Close it and stop watching instead.
1319 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!"; 1307 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!";
1320 inotify_watcher_.StopWatchingFileDescriptor(); 1308 inotify_watcher_.reset();
1321 close(inotify_fd_); 1309 close(inotify_fd_);
1322 inotify_fd_ = -1; 1310 inotify_fd_ = -1;
1323 } 1311 }
1324 } 1312 }
1325 if (kioslaverc_touched) { 1313 if (kioslaverc_touched) {
1326 // We don't use Reset() because the timer may not yet be running. 1314 // We don't use Reset() because the timer may not yet be running.
1327 // (In that case Stop() is a no-op.) 1315 // (In that case Stop() is a no-op.)
1328 debounce_timer_->Stop(); 1316 debounce_timer_->Stop();
1329 debounce_timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds( 1317 debounce_timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
1330 kDebounceTimeoutMilliseconds), this, 1318 kDebounceTimeoutMilliseconds), this,
1331 &SettingGetterImplKDE::OnDebouncedNotification); 1319 &SettingGetterImplKDE::OnDebouncedNotification);
1332 } 1320 }
1333 } 1321 }
1334 1322
1335 typedef std::map<StringSetting, std::string> string_map_type; 1323 typedef std::map<StringSetting, std::string> string_map_type;
1336 typedef std::map<StringListSetting, 1324 typedef std::map<StringListSetting,
1337 std::vector<std::string> > strings_map_type; 1325 std::vector<std::string> > strings_map_type;
1338 1326
1339 int inotify_fd_; 1327 int inotify_fd_;
1340 base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_; 1328 std::unique_ptr<base::FileDescriptorWatcher::Controller> inotify_watcher_;
1341 ProxyConfigServiceLinux::Delegate* notify_delegate_; 1329 ProxyConfigServiceLinux::Delegate* notify_delegate_;
1342 std::unique_ptr<base::OneShotTimer> debounce_timer_; 1330 std::unique_ptr<base::OneShotTimer> debounce_timer_;
1343 base::FilePath kde_config_dir_; 1331 base::FilePath kde_config_dir_;
1344 bool indirect_manual_; 1332 bool indirect_manual_;
1345 bool auto_no_pac_; 1333 bool auto_no_pac_;
1346 bool reversed_bypass_list_; 1334 bool reversed_bypass_list_;
1347 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since 1335 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since
1348 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the 1336 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the
1349 // same lifetime. 1337 // same lifetime.
1350 base::Environment* env_var_getter_; 1338 base::Environment* env_var_getter_;
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { 1770 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) {
1783 delegate_->RemoveObserver(observer); 1771 delegate_->RemoveObserver(observer);
1784 } 1772 }
1785 1773
1786 ProxyConfigService::ConfigAvailability 1774 ProxyConfigService::ConfigAvailability
1787 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { 1775 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) {
1788 return delegate_->GetLatestProxyConfig(config); 1776 return delegate_->GetLatestProxyConfig(config);
1789 } 1777 }
1790 1778
1791 } // namespace net 1779 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698