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

Unified Diff: chrome/browser/sync/engine/net/server_connection_manager.cc

Issue 7792022: sync: abort active HTTP requests on shutdown. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: initial Created 9 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sync/engine/net/server_connection_manager.cc
diff --git a/chrome/browser/sync/engine/net/server_connection_manager.cc b/chrome/browser/sync/engine/net/server_connection_manager.cc
index 8f00369cdb3e1fa6bfcf11af6004d8b81b216abe..d4e01386e3184990611135cd058bd9a1e8076fc9 100644
--- a/chrome/browser/sync/engine/net/server_connection_manager.cc
+++ b/chrome/browser/sync/engine/net/server_connection_manager.cc
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "base/auto_reset.h"
#include "base/command_line.h"
#include "build/build_config.h"
#include "chrome/browser/sync/engine/net/url_translator.h"
@@ -58,7 +59,14 @@ const char* HttpResponse::GetServerConnectionCodeString(
#undef ENUM_CASE
-bool ServerConnectionManager::Post::ReadBufferResponse(
+ServerConnectionManager::Connection::Connection(
+ ServerConnectionManager* scm) : scm_(scm), timing_info_(0) {
+}
+
+ServerConnectionManager::Connection::~Connection() {
+}
+
+bool ServerConnectionManager::Connection::ReadBufferResponse(
string* buffer_out,
HttpResponse* response,
bool require_response) {
@@ -79,7 +87,7 @@ bool ServerConnectionManager::Post::ReadBufferResponse(
return true;
}
-bool ServerConnectionManager::Post::ReadDownloadResponse(
+bool ServerConnectionManager::Connection::ReadDownloadResponse(
HttpResponse* response,
string* buffer_out) {
const int64 bytes_read = ReadResponse(buffer_out,
@@ -108,7 +116,7 @@ string StripTrailingSlash(const string& s) {
} // namespace
// TODO(chron): Use a GURL instead of string concatenation.
-string ServerConnectionManager::Post::MakeConnectionURL(
+string ServerConnectionManager::Connection::MakeConnectionURL(
const string& sync_server,
const string& path,
bool use_ssl) const {
@@ -120,8 +128,8 @@ string ServerConnectionManager::Post::MakeConnectionURL(
return connection_url;
}
-int ServerConnectionManager::Post::ReadResponse(string* out_buffer,
- int length) {
+int ServerConnectionManager::Connection::ReadResponse(string* out_buffer,
+ int length) {
int bytes_read = buffer_.length();
CHECK(length <= bytes_read);
out_buffer->assign(buffer_);
@@ -160,14 +168,16 @@ ServerConnectionManager::ServerConnectionManager(
get_time_path_(kSyncServerGetTimePath),
error_count_(0),
server_status_(HttpResponse::NONE),
- server_reachable_(false) {
+ server_reachable_(false),
+ terminated_(false),
+ active_connection_(false) {
}
ServerConnectionManager::~ServerConnectionManager() {
}
void ServerConnectionManager::NotifyStatusChanged() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
FOR_EACH_OBSERVER(ServerConnectionEventListener, listeners_,
OnServerConnectionEvent(
ServerConnectionEvent(server_status_, server_reachable_)));
@@ -175,7 +185,7 @@ void ServerConnectionManager::NotifyStatusChanged() {
bool ServerConnectionManager::PostBufferWithCachedAuth(
const PostBufferParams* params, ScopedServerStatusWatcher* watcher) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
string path =
MakeSyncServerPath(proto_sync_path(), MakeSyncQueryString(client_id_));
return PostBufferToPath(params, path, auth_token(), watcher);
@@ -184,7 +194,7 @@ bool ServerConnectionManager::PostBufferWithCachedAuth(
bool ServerConnectionManager::PostBufferToPath(const PostBufferParams* params,
const string& path, const string& auth_token,
ScopedServerStatusWatcher* watcher) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(watcher != NULL);
if (auth_token.empty()) {
@@ -192,10 +202,29 @@ bool ServerConnectionManager::PostBufferToPath(const PostBufferParams* params,
return false;
}
- scoped_ptr<Post> post(MakePost());
- post->set_timing_info(params->timing_info);
- bool ok = post->Init(path.c_str(), auth_token, params->buffer_in,
- params->response);
+ // The AutoReset is to temporarily bind active_connection_ to the local
+ // |post|. It's done this way to protect against a race between a call
+ // to Abort and assignment of active_connection_.
akalin 2011/08/31 07:20:39 I don't get it. What race? This still seems racy
tim (not reviewing) 2011/08/31 14:46:17 We have to make sure that if terminate is called,
+ scoped_ptr<Connection> post;
+ scoped_ptr<AutoReset<Connection*> > active_connection_resetter;
+ {
akalin 2011/08/31 07:20:39 I suggest making MakeConnection() (or some non-vir
+ base::AutoLock lock(terminate_connection_lock_);
+ if (terminated_) {
+ params->response->server_status = HttpResponse::CONNECTION_UNAVAILABLE;
+ return false;
+ }
+
+ DCHECK(!active_connection_);
+ post.reset(MakeConnection());
+ active_connection_resetter.reset(
+ new AutoReset<Connection*>(&active_connection_, post.get()));
+ post->set_timing_info(params->timing_info);
+ }
+
+ // Note that |post| may be aborted by now, which will just cause Init to fail
+ // with CONNECTION_UNAVAILABLE.
+ bool ok = active_connection_->Init(
akalin 2011/08/31 07:20:39 clearer to do post->Init() here, I think
+ path.c_str(), auth_token, params->buffer_in, params->response);
if (params->response->server_status == HttpResponse::SYNC_AUTH_ERROR) {
InvalidateAndClearAuthToken();
@@ -215,7 +244,8 @@ bool ServerConnectionManager::PostBufferToPath(const PostBufferParams* params,
}
bool ServerConnectionManager::CheckTime(int32* out_time) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
+
// Verify that the server really is reachable by checking the time. We need
// to do this because of wifi interstitials that intercept messages from the
// client and return HTTP OK instead of a redirect.
@@ -224,7 +254,17 @@ bool ServerConnectionManager::CheckTime(int32* out_time) {
string post_body = "command=get_time";
for (int i = 0 ; i < 3; i++) {
- scoped_ptr<Post> post(MakePost());
+ scoped_ptr<Connection> post;
akalin 2011/08/31 07:20:39 similarly as above, you can just do: scoped_ptr<C
+ scoped_ptr<AutoReset<Connection*> > active_connection_resetter;
+ {
+ base::AutoLock lock(terminate_connection_lock_);
+ if (terminated_)
+ break;
+ DCHECK(!active_connection_);
+ post.reset(MakeConnection());
+ active_connection_resetter.reset(
+ new AutoReset<Connection*>(&active_connection_, post.get()));
+ }
// Note that the server's get_time path doesn't require authentication.
string get_time_path =
@@ -257,18 +297,18 @@ bool ServerConnectionManager::CheckTime(int32* out_time) {
}
bool ServerConnectionManager::IsServerReachable() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
int32 time;
return CheckTime(&time);
}
bool ServerConnectionManager::IsUserAuthenticated() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
return IsGoodReplyFromServer(server_status_);
}
bool ServerConnectionManager::CheckServerReachable() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
const bool server_is_reachable = IsServerReachable();
if (server_reachable_ != server_is_reachable) {
server_reachable_ = server_is_reachable;
@@ -278,7 +318,7 @@ bool ServerConnectionManager::CheckServerReachable() {
}
bool ServerConnectionManager::IncrementErrorCount() {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
error_count_++;
if (error_count_ > kMaxConnectionErrorsBeforeReset) {
@@ -299,7 +339,7 @@ bool ServerConnectionManager::IncrementErrorCount() {
void ServerConnectionManager::SetServerParameters(const string& server_url,
int port,
bool use_ssl) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
sync_server_ = server_url;
sync_server_port_ = port;
use_ssl_ = use_ssl;
@@ -334,20 +374,32 @@ std::string ServerConnectionManager::GetServerHost() const {
void ServerConnectionManager::AddListener(
ServerConnectionEventListener* listener) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
listeners_.AddObserver(listener);
}
void ServerConnectionManager::RemoveListener(
ServerConnectionEventListener* listener) {
- DCHECK(CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
listeners_.RemoveObserver(listener);
}
-ServerConnectionManager::Post* ServerConnectionManager::MakePost() {
+ServerConnectionManager::Connection* ServerConnectionManager::MakeConnection()
+{
return NULL; // For testing.
}
+void ServerConnectionManager::TerminateAllIO() {
+ base::AutoLock lock(terminate_connection_lock_);
+ terminated_ = true;
+ if (active_connection_)
+ active_connection_->Abort();
+
+ // Sever our ties to this connection object. Note that it still may exist,
+ // since we don't own it, but it has been neutered.
+ active_connection_ = NULL;
+}
+
bool FillMessageWithShareDetails(sync_pb::ClientToServerMessage* csm,
syncable::DirectoryManager* manager,
const std::string& share) {

Powered by Google App Engine
This is Rietveld 408576698