Index: chrome/browser/sync/engine/net/server_connection_manager.h |
diff --git a/chrome/browser/sync/engine/net/server_connection_manager.h b/chrome/browser/sync/engine/net/server_connection_manager.h |
index 50f033d28c4a33e6479c6572739fa3eb09061523..9fc9d74cccba47e0e73aed4e9ce4dc8b5e1f3d90 100644 |
--- a/chrome/browser/sync/engine/net/server_connection_manager.h |
+++ b/chrome/browser/sync/engine/net/server_connection_manager.h |
@@ -10,9 +10,11 @@ |
#include <string> |
#include "base/atomicops.h" |
+#include "base/memory/scoped_ptr.h" |
#include "base/observer_list.h" |
#include "base/string_util.h" |
#include "base/threading/non_thread_safe.h" |
+#include "base/threading/thread_checker.h" |
#include "base/synchronization/lock.h" |
#include "chrome/browser/sync/syncable/syncable_id.h" |
#include "chrome/common/net/http_return.h" |
@@ -138,7 +140,7 @@ class ScopedServerStatusWatcher : public base::NonThreadSafe { |
// Use this class to interact with the sync server. |
// The ServerConnectionManager currently supports POSTing protocol buffers. |
// |
-class ServerConnectionManager : public base::NonThreadSafe { |
+class ServerConnectionManager { |
public: |
// buffer_in - will be POSTed |
// buffer_out - string will be overwritten with response |
@@ -151,11 +153,10 @@ class ServerConnectionManager : public base::NonThreadSafe { |
// Abstract class providing network-layer functionality to the |
// ServerConnectionManager. Subclasses implement this using an HTTP stack of |
// their choice. |
- class Post { |
+ class Connection { |
public: |
- explicit Post(ServerConnectionManager* scm) : scm_(scm) { |
- } |
- virtual ~Post() { } |
+ explicit Connection(ServerConnectionManager* scm); |
+ virtual ~Connection(); |
// Called to initialize and perform an HTTP POST. |
virtual bool Init(const char* path, |
@@ -163,6 +164,10 @@ class ServerConnectionManager : public base::NonThreadSafe { |
const std::string& payload, |
HttpResponse* response) = 0; |
+ // Immediately abandons a pending HTTP POST request and unblocks caller |
+ // in Init. |
+ virtual void Abort() = 0; |
+ |
bool ReadBufferResponse(std::string* buffer_out, HttpResponse* response, |
bool require_response); |
bool ReadDownloadResponse(HttpResponse* response, std::string* buffer_out); |
@@ -222,7 +227,7 @@ class ServerConnectionManager : public base::NonThreadSafe { |
inline std::string user_agent() const { return user_agent_; } |
inline HttpResponse::ServerConnectionCode server_status() const { |
- DCHECK(CalledOnValidThread()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
return server_status_; |
} |
@@ -245,19 +250,25 @@ class ServerConnectionManager : public base::NonThreadSafe { |
std::string GetServerHost() const; |
- // Factory method to create a Post object we can use for communication with |
- // the server. |
- virtual Post* MakePost(); |
+ // Factory method to create an Connection object we can use for |
+ // communication with the server. |
+ virtual Connection* MakeConnection(); |
+ |
+ // Aborts any active HTTP POST request. |
+ // We expect this to get called on a different thread than the valid |
+ // ThreadChecker thread, as we want to kill any pending http traffic without |
+ // having to wait for the request to complete. |
+ void TerminateAllIO(); |
void set_client_id(const std::string& client_id) { |
- DCHECK(CalledOnValidThread()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(client_id_.empty()); |
client_id_.assign(client_id); |
} |
// Returns true if the auth token is succesfully set and false otherwise. |
bool set_auth_token(const std::string& auth_token) { |
- DCHECK(CalledOnValidThread()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (previously_invalidated_token != auth_token) { |
auth_token_.assign(auth_token); |
previously_invalidated_token = std::string(); |
@@ -267,7 +278,7 @@ class ServerConnectionManager : public base::NonThreadSafe { |
} |
void InvalidateAndClearAuthToken() { |
- DCHECK(CalledOnValidThread()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Copy over the token to previous invalid token. |
if (!auth_token_.empty()) { |
previously_invalidated_token.assign(auth_token_); |
@@ -276,7 +287,7 @@ class ServerConnectionManager : public base::NonThreadSafe { |
} |
const std::string auth_token() const { |
- DCHECK(CalledOnValidThread()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
return auth_token_; |
} |
@@ -301,6 +312,15 @@ class ServerConnectionManager : public base::NonThreadSafe { |
const std::string& auth_token, |
ScopedServerStatusWatcher* watcher); |
+ // Helper to check terminated flags and build a Connection object, installing |
+ // it as the |active_connection_|. If this ServerConnectionManager has been |
+ // terminated, this will return NULL. |
+ Connection* MakeActiveConnection(); |
+ |
+ // Called by Connection objects as they are destroyed to allow the |
+ // ServerConnectionManager to cleanup active connections. |
+ void OnConnectionDestroyed(Connection* connection); |
+ |
// The sync_server_ is the server that requests will be made to. |
std::string sync_server_; |
@@ -333,10 +353,40 @@ class ServerConnectionManager : public base::NonThreadSafe { |
HttpResponse::ServerConnectionCode server_status_; |
bool server_reachable_; |
+ base::ThreadChecker thread_checker_; |
+ |
+ // Protects all variables below to allow bailing out of active connections. |
+ base::Lock terminate_connection_lock_; |
+ |
+ // If true, we've been told to terminate IO and expect to be destroyed |
+ // shortly. No future network requests will be made. |
+ bool terminated_; |
+ |
+ // A non-owning pointer to any active http connection, so that we can abort |
+ // it if necessary. |
+ Connection* active_connection_; |
+ |
private: |
- friend class Post; |
+ friend class Connection; |
friend class ScopedServerStatusWatcher; |
+ // A class to help deal with cleaning up active Connection objects when (for |
+ // ex) multiple early-exits are present in some scope. ScopedConnectionHelper |
+ // informs the ServerConnectionManager before the Connection object it takes |
+ // ownership of is destroyed. |
+ class ScopedConnectionHelper { |
+ public: |
+ // |manager| must outlive this. Takes ownership of |connection|. |
+ ScopedConnectionHelper(ServerConnectionManager* manager, |
+ Connection* connection); |
+ ~ScopedConnectionHelper(); |
+ Connection* get(); |
+ private: |
+ ServerConnectionManager* manager_; |
+ scoped_ptr<Connection> connection_; |
+ DISALLOW_COPY_AND_ASSIGN(ScopedConnectionHelper); |
+ }; |
+ |
void NotifyStatusChanged(); |
DISALLOW_COPY_AND_ASSIGN(ServerConnectionManager); |