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

Side by Side Diff: remoting/host/config_file_watcher.cc

Issue 10855249: [Chromoting] The daemon process now starts the networking process and passes the host configuration… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added missing signal.h Created 8 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « remoting/host/config_file_watcher.h ('k') | remoting/host/daemon_process.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "remoting/host/config_file_watcher.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/files/file_path_watcher.h"
10 #include "base/file_util.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/timer.h"
15
16 namespace remoting {
17
18 // The name of the command-line switch used to specify the host configuration
19 // file to use.
20 const char kHostConfigSwitchName[] = "host-config";
21
22 const FilePath::CharType kDefaultHostConfigFile[] =
23 FILE_PATH_LITERAL("host.json");
24
25 class ConfigFileWatcherImpl
26 : public base::RefCountedThreadSafe<ConfigFileWatcherImpl> {
27 public:
28 // Creates a configuration file watcher that lives on the |io_task_runner|
29 // thread but posts config file updates on on |main_task_runner|.
30 ConfigFileWatcherImpl(
31 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
32 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
33 ConfigFileWatcher::Delegate* delegate);
34
35 // Starts watching |config_path|.
36 void Watch(const FilePath& config_path);
37
38 // Stops watching the configuration file.
39 void StopWatching();
40
41 private:
42 friend class base::RefCountedThreadSafe<ConfigFileWatcherImpl>;
43 virtual ~ConfigFileWatcherImpl();
44
45 void FinishStopping();
46
47 // Called every time the host configuration file is updated.
48 void OnConfigUpdated(const FilePath& path, bool error);
49
50 // Reads the configuration file and passes it to the delegate.
51 void ReloadConfig();
52
53 FilePath config_path_;
54
55 scoped_ptr<base::DelayTimer<ConfigFileWatcherImpl> > config_updated_timer_;
56
57 // Monitors the host configuration file.
58 scoped_ptr<base::files::FilePathWatcher> config_watcher_;
59
60 base::WeakPtrFactory<ConfigFileWatcher::Delegate> delegate_weak_factory_;
61 base::WeakPtr<ConfigFileWatcher::Delegate> delegate_;
62
63 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
64 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
65
66 DISALLOW_COPY_AND_ASSIGN(ConfigFileWatcherImpl);
67 };
68
69 ConfigFileWatcher::Delegate::~Delegate() {
70 }
71
72 ConfigFileWatcher::ConfigFileWatcher(
73 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
74 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
75 Delegate* delegate)
76 : impl_(new ConfigFileWatcherImpl(main_task_runner,
77 io_task_runner, delegate)) {
78 }
79
80 ConfigFileWatcher::~ConfigFileWatcher() {
81 impl_->StopWatching();
82 impl_ = NULL;
83 }
84
85 void ConfigFileWatcher::Watch(const FilePath& config_path) {
86 impl_->Watch(config_path);
87 }
88
89 ConfigFileWatcherImpl::ConfigFileWatcherImpl(
90 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
91 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
92 ConfigFileWatcher::Delegate* delegate)
93 : delegate_weak_factory_(delegate),
94 delegate_(delegate_weak_factory_.GetWeakPtr()),
95 main_task_runner_(main_task_runner),
96 io_task_runner_(io_task_runner) {
97 DCHECK(main_task_runner_->BelongsToCurrentThread());
98 }
99
100 void ConfigFileWatcherImpl::Watch(const FilePath& config_path) {
101 if (!io_task_runner_->BelongsToCurrentThread()) {
102 io_task_runner_->PostTask(
103 FROM_HERE,
104 base::Bind(&ConfigFileWatcherImpl::Watch, this, config_path));
105 return;
106 }
107
108 DCHECK(config_path_.empty());
109 DCHECK(config_updated_timer_.get() == NULL);
110 DCHECK(config_watcher_.get() == NULL);
111
112 // Create the timer that will be used for delayed-reading the configuration
113 // file.
114 config_updated_timer_.reset(new base::DelayTimer<ConfigFileWatcherImpl>(
115 FROM_HERE, base::TimeDelta::FromSeconds(2), this,
116 &ConfigFileWatcherImpl::ReloadConfig));
117
118 // Start watching the configuration file.
119 config_watcher_.reset(new base::files::FilePathWatcher());
120 config_path_ = config_path;
121 if (!config_watcher_->Watch(
122 config_path_,
123 base::Bind(&ConfigFileWatcherImpl::OnConfigUpdated, this))) {
124 LOG(ERROR) << "Couldn't watch file '" << config_path_.value() << "'";
125 main_task_runner_->PostTask(
126 FROM_HERE,
127 base::Bind(&ConfigFileWatcher::Delegate::OnConfigWatcherError,
128 delegate_));
129 return;
130 }
131
132 // Force reloading of the configuration file at least once.
133 ReloadConfig();
134 }
135
136 void ConfigFileWatcherImpl::StopWatching() {
137 DCHECK(main_task_runner_->BelongsToCurrentThread());
138
139 delegate_weak_factory_.InvalidateWeakPtrs();
140 io_task_runner_->PostTask(
141 FROM_HERE, base::Bind(&ConfigFileWatcherImpl::FinishStopping, this));
142 }
143
144 ConfigFileWatcherImpl::~ConfigFileWatcherImpl() {
145 DCHECK(config_updated_timer_.get() == NULL);
146 DCHECK(config_watcher_.get() == NULL);
147 }
148
149 void ConfigFileWatcherImpl::FinishStopping() {
150 DCHECK(io_task_runner_->BelongsToCurrentThread());
151
152 config_updated_timer_.reset(NULL);
153 config_watcher_.reset(NULL);
154 }
155
156 void ConfigFileWatcherImpl::OnConfigUpdated(const FilePath& path, bool error) {
157 DCHECK(io_task_runner_->BelongsToCurrentThread());
158
159 // Call ReloadConfig() after a short delay, so that we will not try to read
160 // the updated configuration file before it has been completely written.
161 // If the writer moves the new configuration file into place atomically,
162 // this delay may not be necessary.
163 if (!error && config_path_ == path)
164 config_updated_timer_->Reset();
165 }
166
167 void ConfigFileWatcherImpl::ReloadConfig() {
168 DCHECK(io_task_runner_->BelongsToCurrentThread());
169
170 std::string config;
171 if (!file_util::ReadFileToString(config_path_, &config)) {
172 LOG(ERROR) << "Failed to read '" << config_path_.value() << "'";
173 main_task_runner_->PostTask(
174 FROM_HERE,
175 base::Bind(&ConfigFileWatcher::Delegate::OnConfigWatcherError,
176 delegate_));
177 return;
178 }
179
180 main_task_runner_->PostTask(
181 FROM_HERE,
182 base::Bind(&ConfigFileWatcher::Delegate::OnConfigUpdated, delegate_,
183 config));
184 }
185
186 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/config_file_watcher.h ('k') | remoting/host/daemon_process.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698