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

Side by Side Diff: trunk/src/sync/engine/net/server_connection_manager.cc

Issue 23658030: Revert 222154 "sync: Gracefully handle very early shutdown" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 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
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 "sync/engine/net/server_connection_manager.h" 5 #include "sync/engine/net/server_connection_manager.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 8
9 #include <ostream> 9 #include <ostream>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "build/build_config.h" 14 #include "build/build_config.h"
15 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
16 #include "net/http/http_status_code.h" 16 #include "net/http/http_status_code.h"
17 #include "sync/engine/net/url_translator.h" 17 #include "sync/engine/net/url_translator.h"
18 #include "sync/engine/syncer.h" 18 #include "sync/engine/syncer.h"
19 #include "sync/internal_api/public/base/cancelation_signal.h"
20 #include "sync/protocol/sync.pb.h" 19 #include "sync/protocol/sync.pb.h"
21 #include "sync/syncable/directory.h" 20 #include "sync/syncable/directory.h"
22 #include "url/gurl.h" 21 #include "url/gurl.h"
23 22
24 namespace syncer { 23 namespace syncer {
25 24
26 using std::ostream; 25 using std::ostream;
27 using std::string; 26 using std::string;
28 using std::vector; 27 using std::vector;
29 28
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 if (bytes_read != response->content_length) { 107 if (bytes_read != response->content_length) {
109 LOG(ERROR) << "Mismatched content lengths, server claimed " << 108 LOG(ERROR) << "Mismatched content lengths, server claimed " <<
110 response->content_length << ", but sent " << bytes_read; 109 response->content_length << ", but sent " << bytes_read;
111 response->server_status = HttpResponse::IO_ERROR; 110 response->server_status = HttpResponse::IO_ERROR;
112 return false; 111 return false;
113 } 112 }
114 return true; 113 return true;
115 } 114 }
116 115
117 ServerConnectionManager::ScopedConnectionHelper::ScopedConnectionHelper( 116 ServerConnectionManager::ScopedConnectionHelper::ScopedConnectionHelper(
118 CancelationSignal* signaller, scoped_ptr<Connection> connection) 117 ServerConnectionManager* manager, Connection* connection)
119 : cancelation_signal_(signaller), connection_(connection.Pass()) { 118 : manager_(manager), connection_(connection) {}
120 // Special early return for tests.
121 if (!connection_.get())
122 return;
123
124 if (!cancelation_signal_->TryRegisterHandler(this)) {
125 connection_.reset();
126 }
127 }
128
129 // This function may be called from another thread.
130 void ServerConnectionManager::ScopedConnectionHelper::OnStopRequested() {
131 DCHECK(connection_);
132 connection_->Abort();
133 }
134 119
135 ServerConnectionManager::ScopedConnectionHelper::~ScopedConnectionHelper() { 120 ServerConnectionManager::ScopedConnectionHelper::~ScopedConnectionHelper() {
136 // We should be registered iff connection_.get() != NULL. 121 if (connection_)
137 if (connection_.get()) { 122 manager_->OnConnectionDestroyed(connection_.get());
138 // It is important that this be called before this destructor completes. 123 connection_.reset();
139 // Until the unregistration is complete, it's possible that the virtual
140 // OnStopRequested() function may be called from a different thread. We
141 // need to unregister it before destruction modifies our vptr.
142 cancelation_signal_->UnregisterHandler(this);
143 }
144 } 124 }
145 125
146 ServerConnectionManager::Connection* 126 ServerConnectionManager::Connection*
147 ServerConnectionManager::ScopedConnectionHelper::get() { 127 ServerConnectionManager::ScopedConnectionHelper::get() {
148 return connection_.get(); 128 return connection_.get();
149 } 129 }
150 130
151 namespace { 131 namespace {
152 132
153 string StripTrailingSlash(const string& s) { 133 string StripTrailingSlash(const string& s) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 } 170 }
191 171
192 ScopedServerStatusWatcher::~ScopedServerStatusWatcher() { 172 ScopedServerStatusWatcher::~ScopedServerStatusWatcher() {
193 conn_mgr_->SetServerStatus(response_->server_status); 173 conn_mgr_->SetServerStatus(response_->server_status);
194 } 174 }
195 175
196 ServerConnectionManager::ServerConnectionManager( 176 ServerConnectionManager::ServerConnectionManager(
197 const string& server, 177 const string& server,
198 int port, 178 int port,
199 bool use_ssl, 179 bool use_ssl,
200 bool use_oauth2_token, 180 bool use_oauth2_token)
201 CancelationSignal* cancelation_signal)
202 : sync_server_(server), 181 : sync_server_(server),
203 sync_server_port_(port), 182 sync_server_port_(port),
204 use_ssl_(use_ssl), 183 use_ssl_(use_ssl),
205 use_oauth2_token_(use_oauth2_token), 184 use_oauth2_token_(use_oauth2_token),
206 proto_sync_path_(kSyncServerSyncPath), 185 proto_sync_path_(kSyncServerSyncPath),
207 server_status_(HttpResponse::NONE), 186 server_status_(HttpResponse::NONE),
208 cancelation_signal_(cancelation_signal) { 187 terminated_(false),
188 active_connection_(NULL) {
209 } 189 }
210 190
211 ServerConnectionManager::~ServerConnectionManager() { 191 ServerConnectionManager::~ServerConnectionManager() {
212 } 192 }
213 193
194 ServerConnectionManager::Connection*
195 ServerConnectionManager::MakeActiveConnection() {
196 base::AutoLock lock(terminate_connection_lock_);
197 DCHECK(!active_connection_);
198 if (terminated_)
199 return NULL;
200
201 active_connection_ = MakeConnection();
202 return active_connection_;
203 }
204
205 void ServerConnectionManager::OnConnectionDestroyed(Connection* connection) {
206 DCHECK(connection);
207 base::AutoLock lock(terminate_connection_lock_);
208 // |active_connection_| can be NULL already if it was aborted. Also,
209 // it can legitimately be a different Connection object if a new Connection
210 // was created after a previous one was Aborted and destroyed.
211 if (active_connection_ != connection)
212 return;
213
214 active_connection_ = NULL;
215 }
216
214 bool ServerConnectionManager::SetAuthToken(const std::string& auth_token) { 217 bool ServerConnectionManager::SetAuthToken(const std::string& auth_token) {
215 DCHECK(thread_checker_.CalledOnValidThread()); 218 DCHECK(thread_checker_.CalledOnValidThread());
216 if (previously_invalidated_token != auth_token) { 219 if (previously_invalidated_token != auth_token) {
217 auth_token_.assign(auth_token); 220 auth_token_.assign(auth_token);
218 previously_invalidated_token = std::string(); 221 previously_invalidated_token = std::string();
219 return true; 222 return true;
220 } 223 }
221 return false; 224 return false;
222 } 225 }
223 226
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 // workaround for M29 blocker to avoid sending RPC to sync with known invalid 271 // workaround for M29 blocker to avoid sending RPC to sync with known invalid
269 // token but instead to trigger refreshing token in ProfileSyncService. Need 272 // token but instead to trigger refreshing token in ProfileSyncService. Need
270 // to clean it. 273 // to clean it.
271 if (auth_token.empty() || auth_token == "credentials_lost") { 274 if (auth_token.empty() || auth_token == "credentials_lost") {
272 params->response.server_status = HttpResponse::SYNC_AUTH_ERROR; 275 params->response.server_status = HttpResponse::SYNC_AUTH_ERROR;
273 return false; 276 return false;
274 } 277 }
275 278
276 // When our connection object falls out of scope, it clears itself from 279 // When our connection object falls out of scope, it clears itself from
277 // active_connection_. 280 // active_connection_.
278 ScopedConnectionHelper post(cancelation_signal_, MakeConnection()); 281 ScopedConnectionHelper post(this, MakeActiveConnection());
279 if (!post.get()) { 282 if (!post.get()) {
280 params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE; 283 params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE;
281 return false; 284 return false;
282 } 285 }
283 286
284 // Note that |post| may be aborted by now, which will just cause Init to fail 287 // Note that |post| may be aborted by now, which will just cause Init to fail
285 // with CONNECTION_UNAVAILABLE. 288 // with CONNECTION_UNAVAILABLE.
286 bool ok = post.get()->Init( 289 bool ok = post.get()->Init(
287 path.c_str(), auth_token, params->buffer_in, &params->response); 290 path.c_str(), auth_token, params->buffer_in, &params->response);
288 291
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 DCHECK(thread_checker_.CalledOnValidThread()); 336 DCHECK(thread_checker_.CalledOnValidThread());
334 listeners_.AddObserver(listener); 337 listeners_.AddObserver(listener);
335 } 338 }
336 339
337 void ServerConnectionManager::RemoveListener( 340 void ServerConnectionManager::RemoveListener(
338 ServerConnectionEventListener* listener) { 341 ServerConnectionEventListener* listener) {
339 DCHECK(thread_checker_.CalledOnValidThread()); 342 DCHECK(thread_checker_.CalledOnValidThread());
340 listeners_.RemoveObserver(listener); 343 listeners_.RemoveObserver(listener);
341 } 344 }
342 345
343 scoped_ptr<ServerConnectionManager::Connection> 346 ServerConnectionManager::Connection* ServerConnectionManager::MakeConnection()
344 ServerConnectionManager::MakeConnection()
345 { 347 {
346 return scoped_ptr<Connection>(); // For testing. 348 return NULL; // For testing.
349 }
350
351 void ServerConnectionManager::TerminateAllIO() {
352 base::AutoLock lock(terminate_connection_lock_);
353 terminated_ = true;
354 if (active_connection_)
355 active_connection_->Abort();
356
357 // Sever our ties to this connection object. Note that it still may exist,
358 // since we don't own it, but it has been neutered.
359 active_connection_ = NULL;
347 } 360 }
348 361
349 std::ostream& operator << (std::ostream& s, const struct HttpResponse& hr) { 362 std::ostream& operator << (std::ostream& s, const struct HttpResponse& hr) {
350 s << " Response Code (bogus on error): " << hr.response_code; 363 s << " Response Code (bogus on error): " << hr.response_code;
351 s << " Content-Length (bogus on error): " << hr.content_length; 364 s << " Content-Length (bogus on error): " << hr.content_length;
352 s << " Server Status: " 365 s << " Server Status: "
353 << HttpResponse::GetServerConnectionCodeString(hr.server_status); 366 << HttpResponse::GetServerConnectionCodeString(hr.server_status);
354 return s; 367 return s;
355 } 368 }
356 369
357 } // namespace syncer 370 } // namespace syncer
OLDNEW
« no previous file with comments | « trunk/src/sync/engine/net/server_connection_manager.h ('k') | trunk/src/sync/engine/sync_scheduler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698