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

Side by Side Diff: chrome/common/service_process_util_posix.cc

Issue 2438913003: Require FilePathWatcher destructor to be called in sequence with Watch(). (Closed)
Patch Set: CR thestig #36 (fix comment) Created 4 years, 1 month 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 | « chrome/common/service_process_util_posix.h ('k') | chrome/common/service_process_util_win.cc » ('j') | 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 "chrome/common/service_process_util_posix.h" 5 #include "chrome/common/service_process_util_posix.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <memory> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/posix/eintr_wrapper.h" 13 #include "base/posix/eintr_wrapper.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
16 #include "build/build_config.h"
17 #include "chrome/common/multi_process_lock.h" 15 #include "chrome/common/multi_process_lock.h"
18 16
19 namespace { 17 namespace {
20 int g_signal_socket = -1; 18 int g_signal_socket = -1;
21 } 19 }
22 20
23 // Attempts to take a lock named |name|. If |waiting| is true then this will 21 // Attempts to take a lock named |name|. If |waiting| is true then this will
24 // make multiple attempts to acquire the lock. 22 // make multiple attempts to acquire the lock.
25 // Caller is responsible for ownership of the MultiProcessLock. 23 // Caller is responsible for ownership of the MultiProcessLock.
26 MultiProcessLock* TakeNamedLock(const std::string& name, bool waiting) { 24 MultiProcessLock* TakeNamedLock(const std::string& name, bool waiting) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 } 80 }
83 } 81 }
84 82
85 ServiceProcessState::StateData::StateData() : set_action(false) { 83 ServiceProcessState::StateData::StateData() : set_action(false) {
86 memset(sockets, -1, sizeof(sockets)); 84 memset(sockets, -1, sizeof(sockets));
87 memset(&old_action, 0, sizeof(old_action)); 85 memset(&old_action, 0, sizeof(old_action));
88 } 86 }
89 87
90 void ServiceProcessState::StateData::SignalReady(base::WaitableEvent* signal, 88 void ServiceProcessState::StateData::SignalReady(base::WaitableEvent* signal,
91 bool* success) { 89 bool* success) {
90 DCHECK(task_runner->BelongsToCurrentThread());
92 DCHECK_EQ(g_signal_socket, -1); 91 DCHECK_EQ(g_signal_socket, -1);
93 DCHECK(!signal->IsSignaled()); 92 DCHECK(!signal->IsSignaled());
94 *success = base::MessageLoopForIO::current()->WatchFileDescriptor( 93 *success = base::MessageLoopForIO::current()->WatchFileDescriptor(
95 sockets[0], 94 sockets[0],
96 true, 95 true,
97 base::MessageLoopForIO::WATCH_READ, 96 base::MessageLoopForIO::WATCH_READ,
98 &watcher, 97 &watcher,
99 terminate_monitor.get()); 98 terminate_monitor.get());
100 if (!*success) { 99 if (!*success) {
101 DLOG(ERROR) << "WatchFileDescriptor"; 100 DLOG(ERROR) << "WatchFileDescriptor";
(...skipping 28 matching lines...) Expand all
130 signal->Signal(); 129 signal->Signal();
131 return; 130 return;
132 } 131 }
133 #elif defined(OS_POSIX) 132 #elif defined(OS_POSIX)
134 initializing_lock.reset(); 133 initializing_lock.reset();
135 #endif // OS_POSIX 134 #endif // OS_POSIX
136 signal->Signal(); 135 signal->Signal();
137 } 136 }
138 137
139 ServiceProcessState::StateData::~StateData() { 138 ServiceProcessState::StateData::~StateData() {
139 // StateData is destroyed on the thread that called SignalReady() (if any) to
140 // satisfy the requirement that base::FilePathWatcher is destroyed in sequence
141 // with base::FilePathWatcher::Watch().
142 DCHECK(!task_runner || task_runner->BelongsToCurrentThread());
143
140 if (sockets[0] != -1) { 144 if (sockets[0] != -1) {
141 if (IGNORE_EINTR(close(sockets[0]))) { 145 if (IGNORE_EINTR(close(sockets[0]))) {
142 DPLOG(ERROR) << "close"; 146 DPLOG(ERROR) << "close";
143 } 147 }
144 } 148 }
145 if (sockets[1] != -1) { 149 if (sockets[1] != -1) {
146 if (IGNORE_EINTR(close(sockets[1]))) { 150 if (IGNORE_EINTR(close(sockets[1]))) {
147 DPLOG(ERROR) << "close"; 151 DPLOG(ERROR) << "close";
148 } 152 }
149 } 153 }
150 if (set_action) { 154 if (set_action) {
151 if (sigaction(SIGTERM, &old_action, NULL) < 0) { 155 if (sigaction(SIGTERM, &old_action, NULL) < 0) {
152 DPLOG(ERROR) << "sigaction"; 156 DPLOG(ERROR) << "sigaction";
153 } 157 }
154 } 158 }
155 g_signal_socket = -1; 159 g_signal_socket = -1;
156 } 160 }
157 161
158 void ServiceProcessState::CreateState() { 162 void ServiceProcessState::CreateState() {
159 DCHECK(!state_); 163 DCHECK(!state_);
160 state_ = new StateData; 164 state_ = new StateData();
161
162 // Explicitly adding a reference here (and removing it in TearDownState)
163 // because StateData is refcounted on Mac and Linux so that methods can
164 // be called on other threads.
165 // It is not refcounted on Windows at this time.
166 state_->AddRef();
167 } 165 }
168 166
169 bool ServiceProcessState::SignalReady(base::SingleThreadTaskRunner* task_runner, 167 bool ServiceProcessState::SignalReady(
170 const base::Closure& terminate_task) { 168 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
169 const base::Closure& terminate_task) {
170 DCHECK(task_runner);
171 DCHECK(state_); 171 DCHECK(state_);
172 172
173 #if defined(OS_POSIX) && !defined(OS_MACOSX) 173 #if !defined(OS_MACOSX)
174 state_->running_lock.reset(TakeServiceRunningLock(true)); 174 state_->running_lock.reset(TakeServiceRunningLock(true));
175 if (state_->running_lock.get() == NULL) { 175 if (state_->running_lock.get() == NULL) {
176 return false; 176 return false;
177 } 177 }
178 #endif 178 #endif
179 state_->terminate_monitor.reset( 179 state_->terminate_monitor.reset(
180 new ServiceProcessTerminateMonitor(terminate_task)); 180 new ServiceProcessTerminateMonitor(terminate_task));
181 if (pipe(state_->sockets) < 0) { 181 if (pipe(state_->sockets) < 0) {
182 DPLOG(ERROR) << "pipe"; 182 DPLOG(ERROR) << "pipe";
183 return false; 183 return false;
184 } 184 }
185 base::WaitableEvent signal_ready( 185 base::WaitableEvent signal_ready(
186 base::WaitableEvent::ResetPolicy::MANUAL, 186 base::WaitableEvent::ResetPolicy::MANUAL,
187 base::WaitableEvent::InitialState::NOT_SIGNALED); 187 base::WaitableEvent::InitialState::NOT_SIGNALED);
188 bool success = false; 188 bool success = false;
189 189
190 task_runner->PostTask(FROM_HERE, 190 state_->task_runner = std::move(task_runner);
191 base::Bind(&ServiceProcessState::StateData::SignalReady, 191 state_->task_runner->PostTask(
192 state_, &signal_ready, &success)); 192 FROM_HERE, base::Bind(&ServiceProcessState::StateData::SignalReady,
193 base::Unretained(state_), &signal_ready, &success));
193 signal_ready.Wait(); 194 signal_ready.Wait();
194 return success; 195 return success;
195 } 196 }
196 197
197 void ServiceProcessState::TearDownState() { 198 void ServiceProcessState::TearDownState() {
198 if (state_) { 199 if (state_ && state_->task_runner)
199 state_->Release(); 200 state_->task_runner->DeleteSoon(FROM_HERE, state_);
200 state_ = NULL; 201 else
201 } 202 delete state_;
203 state_ = nullptr;
202 } 204 }
OLDNEW
« no previous file with comments | « chrome/common/service_process_util_posix.h ('k') | chrome/common/service_process_util_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698