Index: net/socket/client_socket_pool_base.cc |
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc |
index 334a9dc454a5833770fe5a7b75452b1fc10c56ba..c239c694ecaee75c3dc79d128cc8f5a29344c385 100644 |
--- a/net/socket/client_socket_pool_base.cc |
+++ b/net/socket/client_socket_pool_base.cc |
@@ -138,7 +138,6 @@ ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( |
used_idle_socket_timeout_(used_idle_socket_timeout), |
connect_job_factory_(connect_job_factory), |
backup_jobs_enabled_(false), |
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
pool_generation_number_(0), |
in_destructor_(false) { |
DCHECK_LE(0, max_sockets_per_group); |
@@ -188,7 +187,7 @@ int ClientSocketPoolBaseHelper::RequestSocket( |
const std::string& group_name, |
const Request* request) { |
request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
- Group& group = group_map_[group_name]; |
+ Group* group = GetOrCreateGroup(group_name); |
int rv = RequestSocketInternal(group_name, request); |
if (rv != ERR_IO_PENDING) { |
@@ -196,7 +195,7 @@ int ClientSocketPoolBaseHelper::RequestSocket( |
CHECK(!request->handle()->is_initialized()); |
delete request; |
} else { |
- InsertRequestIntoQueue(request, &group.pending_requests); |
+ InsertRequestIntoQueue(request, group->mutable_pending_requests()); |
} |
return rv; |
} |
@@ -209,14 +208,14 @@ int ClientSocketPoolBaseHelper::RequestSocketInternal( |
CHECK(callback); |
ClientSocketHandle* const handle = request->handle(); |
CHECK(handle); |
- Group& group = group_map_[group_name]; |
+ Group* group = GetOrCreateGroup(group_name); |
// Try to reuse a socket. |
- if (AssignIdleSocketToGroup(&group, request)) |
+ if (AssignIdleSocketToGroup(request, group)) |
return OK; |
// Can we make another active socket now? |
- if (!group.HasAvailableSocketSlot(max_sockets_per_group_)) { |
+ if (!group->HasAvailableSocketSlot(max_sockets_per_group_)) { |
request->net_log().AddEvent( |
NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP, NULL); |
return ERR_IO_PENDING; |
@@ -242,31 +241,26 @@ int ClientSocketPoolBaseHelper::RequestSocketInternal( |
if (rv == OK) { |
LogBoundConnectJobToRequest(connect_job->net_log().source(), request); |
HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, |
- handle, base::TimeDelta(), &group, request->net_log()); |
+ handle, base::TimeDelta(), group, request->net_log()); |
} else if (rv == ERR_IO_PENDING) { |
// If we don't have any sockets in this group, set a timer for potentially |
// creating a new one. If the SYN is lost, this backup socket may complete |
// before the slow socket, improving end user latency. |
- if (group.IsEmpty() && !group.backup_job && backup_jobs_enabled_) { |
- group.backup_job = connect_job_factory_->NewConnectJob(group_name, |
- *request, |
- this); |
- StartBackupSocketTimer(group_name); |
- } |
+ if (group->IsEmpty() && !group->HasBackupJob() && backup_jobs_enabled_) |
+ group->StartBackupSocketTimer(group_name, this); |
connecting_socket_count_++; |
- ConnectJob* job = connect_job.release(); |
- group.jobs.insert(job); |
+ group->AddJob(connect_job.release()); |
} else { |
LogBoundConnectJobToRequest(connect_job->net_log().source(), request); |
connect_job->GetAdditionalErrorState(handle); |
ClientSocket* error_socket = connect_job->ReleaseSocket(); |
if (error_socket) { |
HandOutSocket(error_socket, false /* not reused */, handle, |
- base::TimeDelta(), &group, request->net_log()); |
- } else if (group.IsEmpty()) { |
- group_map_.erase(group_name); |
+ base::TimeDelta(), group, request->net_log()); |
+ } else if (group->IsEmpty()) { |
+ RemoveGroup(group_name); |
} |
} |
@@ -274,12 +268,12 @@ int ClientSocketPoolBaseHelper::RequestSocketInternal( |
} |
bool ClientSocketPoolBaseHelper::AssignIdleSocketToGroup( |
- Group* group, const Request* request) { |
+ const Request* request, Group* group) { |
// Iterate through the list of idle sockets until we find one or exhaust |
// the list. |
- while (!group->idle_sockets.empty()) { |
- IdleSocket idle_socket = group->idle_sockets.back(); |
- group->idle_sockets.pop_back(); |
+ while (!group->idle_sockets().empty()) { |
+ IdleSocket idle_socket = group->idle_sockets().back(); |
+ group->mutable_idle_sockets()->pop_back(); |
DecrementIdleCount(); |
if (idle_socket.socket->IsConnectedAndIdle()) { |
// We found one we can reuse! |
@@ -303,60 +297,6 @@ void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( |
new NetLogSourceParameter("source_dependency", connect_job_source)); |
} |
-void ClientSocketPoolBaseHelper::StartBackupSocketTimer( |
- const std::string& group_name) { |
- CHECK(ContainsKey(group_map_, group_name)); |
- Group& group = group_map_[group_name]; |
- |
- // Only allow one timer pending to create a backup socket. |
- if (group.backup_task) |
- return; |
- |
- group.backup_task = method_factory_.NewRunnableMethod( |
- &ClientSocketPoolBaseHelper::OnBackupSocketTimerFired, group_name); |
- MessageLoop::current()->PostDelayedTask(FROM_HERE, group.backup_task, |
- ConnectRetryIntervalMs()); |
-} |
- |
-void ClientSocketPoolBaseHelper::OnBackupSocketTimerFired( |
- const std::string& group_name) { |
- CHECK(ContainsKey(group_map_, group_name)); |
- |
- Group& group = group_map_[group_name]; |
- |
- CHECK(group.backup_task); |
- group.backup_task = NULL; |
- |
- CHECK(group.backup_job); |
- |
- // If there are no more jobs pending, there is no work to do. |
- // If we've done our cleanups correctly, this should not happen. |
- if (group.jobs.empty()) { |
- NOTREACHED(); |
- return; |
- } |
- |
- // If our backup job is waiting on DNS, or if we can't create any sockets |
- // right now due to limits, just reset the timer. |
- if (ReachedMaxSocketsLimit() || |
- !group.HasAvailableSocketSlot(max_sockets_per_group_) || |
- (*group.jobs.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) { |
- StartBackupSocketTimer(group_name); |
- return; |
- } |
- |
- group.backup_job->net_log().AddEvent(NetLog::TYPE_SOCKET_BACKUP_CREATED, |
- NULL); |
- SIMPLE_STATS_COUNTER("socket.backup_created"); |
- int rv = group.backup_job->Connect(); |
- connecting_socket_count_++; |
- group.jobs.insert(group.backup_job); |
- ConnectJob* job = group.backup_job; |
- group.backup_job = NULL; |
- if (rv != ERR_IO_PENDING) |
- OnConnectJobComplete(rv, job); |
-} |
- |
void ClientSocketPoolBaseHelper::CancelRequest( |
const std::string& group_name, ClientSocketHandle* handle) { |
PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); |
@@ -374,20 +314,21 @@ void ClientSocketPoolBaseHelper::CancelRequest( |
CHECK(ContainsKey(group_map_, group_name)); |
- Group& group = group_map_[group_name]; |
+ Group* group = GetOrCreateGroup(group_name); |
// Search pending_requests for matching handle. |
- RequestQueue::iterator it = group.pending_requests.begin(); |
- for (; it != group.pending_requests.end(); ++it) { |
+ RequestQueue::iterator it = group->mutable_pending_requests()->begin(); |
+ for (; it != group->pending_requests().end(); ++it) { |
if ((*it)->handle() == handle) { |
- const Request* req = RemoveRequestFromQueue(it, &group.pending_requests); |
+ const Request* req = |
+ RemoveRequestFromQueue(it, group->mutable_pending_requests()); |
req->net_log().AddEvent(NetLog::TYPE_CANCELLED, NULL); |
req->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
delete req; |
// We let the job run, unless we're at the socket limit. |
- if (group.jobs.size() && ReachedMaxSocketsLimit()) { |
- RemoveConnectJob(*group.jobs.begin(), &group); |
+ if (group->jobs().size() && ReachedMaxSocketsLimit()) { |
+ RemoveConnectJob(*group->jobs().begin(), group); |
CheckForStalledSocketGroups(); |
} |
break; |
@@ -404,7 +345,7 @@ int ClientSocketPoolBaseHelper::IdleSocketCountInGroup( |
GroupMap::const_iterator i = group_map_.find(group_name); |
CHECK(i != group_map_.end()); |
- return i->second.idle_sockets.size(); |
+ return i->second->idle_sockets().size(); |
} |
LoadState ClientSocketPoolBaseHelper::GetLoadState( |
@@ -420,16 +361,16 @@ LoadState ClientSocketPoolBaseHelper::GetLoadState( |
} |
// Can't use operator[] since it is non-const. |
- const Group& group = group_map_.find(group_name)->second; |
+ const Group& group = *group_map_.find(group_name)->second; |
// Search pending_requests for matching handle. |
- RequestQueue::const_iterator it = group.pending_requests.begin(); |
- for (size_t i = 0; it != group.pending_requests.end(); ++it, ++i) { |
+ RequestQueue::const_iterator it = group.pending_requests().begin(); |
+ for (size_t i = 0; it != group.pending_requests().end(); ++it, ++i) { |
if ((*it)->handle() == handle) { |
- if (i < group.jobs.size()) { |
+ if (i < group.jobs().size()) { |
LoadState max_state = LOAD_STATE_IDLE; |
- for (ConnectJobSet::const_iterator job_it = group.jobs.begin(); |
- job_it != group.jobs.end(); ++job_it) { |
+ for (ConnectJobSet::const_iterator job_it = group.jobs().begin(); |
+ job_it != group.jobs().end(); ++job_it) { |
max_state = std::max(max_state, (*job_it)->GetLoadState()); |
} |
return max_state; |
@@ -471,15 +412,15 @@ void ClientSocketPoolBaseHelper::CleanupIdleSockets(bool force) { |
GroupMap::iterator i = group_map_.begin(); |
while (i != group_map_.end()) { |
- Group& group = i->second; |
+ Group* group = i->second; |
- std::deque<IdleSocket>::iterator j = group.idle_sockets.begin(); |
- while (j != group.idle_sockets.end()) { |
+ std::deque<IdleSocket>::iterator j = group->mutable_idle_sockets()->begin(); |
+ while (j != group->idle_sockets().end()) { |
base::TimeDelta timeout = |
j->used ? used_idle_socket_timeout_ : unused_idle_socket_timeout_; |
if (force || j->ShouldCleanup(now, timeout)) { |
delete j->socket; |
- j = group.idle_sockets.erase(j); |
+ j = group->mutable_idle_sockets()->erase(j); |
DecrementIdleCount(); |
} else { |
++j; |
@@ -487,14 +428,36 @@ void ClientSocketPoolBaseHelper::CleanupIdleSockets(bool force) { |
} |
// Delete group if no longer needed. |
- if (group.IsEmpty()) { |
- group_map_.erase(i++); |
+ if (group->IsEmpty()) { |
+ RemoveGroup(i++); |
} else { |
++i; |
} |
} |
} |
+ClientSocketPoolBaseHelper::Group* ClientSocketPoolBaseHelper::GetOrCreateGroup( |
+ const std::string& group_name) { |
+ GroupMap::iterator it = group_map_.find(group_name); |
+ if (it != group_map_.end()) |
+ return it->second; |
+ Group* group = new Group; |
+ group_map_[group_name] = group; |
+ return group; |
+} |
+ |
+void ClientSocketPoolBaseHelper::RemoveGroup(const std::string& group_name) { |
+ GroupMap::iterator it = group_map_.find(group_name); |
+ CHECK(it != group_map_.end()); |
+ |
+ RemoveGroup(it); |
+} |
+ |
+void ClientSocketPoolBaseHelper::RemoveGroup(GroupMap::iterator it) { |
+ delete it->second; |
+ group_map_.erase(it); |
+} |
+ |
void ClientSocketPoolBaseHelper::IncrementIdleCount() { |
if (++idle_socket_count_ == 1) |
timer_.Start(TimeDelta::FromSeconds(kCleanupInterval), this, |
@@ -512,20 +475,20 @@ void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name, |
GroupMap::iterator i = group_map_.find(group_name); |
CHECK(i != group_map_.end()); |
- Group& group = i->second; |
+ Group* group = i->second; |
CHECK_GT(handed_out_socket_count_, 0); |
handed_out_socket_count_--; |
- CHECK_GT(group.active_socket_count, 0); |
- group.active_socket_count--; |
+ CHECK_GT(group->active_socket_count(), 0); |
+ group->DecrementActiveSocketCount(); |
const bool can_reuse = socket->IsConnectedAndIdle() && |
id == pool_generation_number_; |
if (can_reuse) { |
// Add it to the idle list. |
- AddIdleSocket(socket, true /* used socket */, &group); |
- OnAvailableSocketSlot(group_name, &group); |
+ AddIdleSocket(socket, true /* used socket */, group); |
+ OnAvailableSocketSlot(group_name, group); |
} else { |
delete socket; |
} |
@@ -568,16 +531,16 @@ bool ClientSocketPoolBaseHelper::FindTopStalledGroup(Group** group, |
bool has_stalled_group = false; |
for (GroupMap::iterator i = group_map_.begin(); |
i != group_map_.end(); ++i) { |
- Group& group = i->second; |
- const RequestQueue& queue = group.pending_requests; |
+ Group* curr_group = i->second; |
+ const RequestQueue& queue = curr_group->pending_requests(); |
if (queue.empty()) |
continue; |
- if (group.IsStalled(max_sockets_per_group_)) { |
+ if (curr_group->IsStalled(max_sockets_per_group_)) { |
has_stalled_group = true; |
bool has_higher_priority = !top_group || |
- group.TopPendingPriority() < top_group->TopPendingPriority(); |
+ curr_group->TopPendingPriority() < top_group->TopPendingPriority(); |
if (has_higher_priority) { |
- top_group = &group; |
+ top_group = curr_group; |
top_group_name = &i->first; |
} |
} |
@@ -596,7 +559,7 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( |
const std::string group_name = job->group_name(); |
GroupMap::iterator group_it = group_map_.find(group_name); |
CHECK(group_it != group_map_.end()); |
- Group& group = group_it->second; |
+ Group* group = group_it->second; |
scoped_ptr<ClientSocket> socket(job->ReleaseSocket()); |
@@ -604,44 +567,46 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( |
if (result == OK) { |
DCHECK(socket.get()); |
- RemoveConnectJob(job, &group); |
- if (!group.pending_requests.empty()) { |
+ RemoveConnectJob(job, group); |
+ if (!group->pending_requests().empty()) { |
scoped_ptr<const Request> r(RemoveRequestFromQueue( |
- group.pending_requests.begin(), &group.pending_requests)); |
+ group->mutable_pending_requests()->begin(), |
+ group->mutable_pending_requests())); |
LogBoundConnectJobToRequest(job_log.source(), r.get()); |
HandOutSocket( |
socket.release(), false /* unused socket */, r->handle(), |
- base::TimeDelta(), &group, r->net_log()); |
+ base::TimeDelta(), group, r->net_log()); |
r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
InvokeUserCallbackLater(r->handle(), r->callback(), result); |
} else { |
- AddIdleSocket(socket.release(), false /* unused socket */, &group); |
- OnAvailableSocketSlot(group_name, &group); |
+ AddIdleSocket(socket.release(), false /* unused socket */, group); |
+ OnAvailableSocketSlot(group_name, group); |
CheckForStalledSocketGroups(); |
} |
} else { |
// If we got a socket, it must contain error information so pass that |
// up so that the caller can retrieve it. |
bool handed_out_socket = false; |
- if (!group.pending_requests.empty()) { |
+ if (!group->pending_requests().empty()) { |
scoped_ptr<const Request> r(RemoveRequestFromQueue( |
- group.pending_requests.begin(), &group.pending_requests)); |
+ group->mutable_pending_requests()->begin(), |
+ group->mutable_pending_requests())); |
LogBoundConnectJobToRequest(job_log.source(), r.get()); |
job->GetAdditionalErrorState(r->handle()); |
- RemoveConnectJob(job, &group); |
+ RemoveConnectJob(job, group); |
if (socket.get()) { |
handed_out_socket = true; |
HandOutSocket(socket.release(), false /* unused socket */, r->handle(), |
- base::TimeDelta(), &group, r->net_log()); |
+ base::TimeDelta(), group, r->net_log()); |
} |
r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, |
new NetLogIntegerParameter("net_error", result)); |
InvokeUserCallbackLater(r->handle(), r->callback(), result); |
} else { |
- RemoveConnectJob(job, &group); |
+ RemoveConnectJob(job, group); |
} |
if (!handed_out_socket) { |
- OnAvailableSocketSlot(group_name, &group); |
+ OnAvailableSocketSlot(group_name, group); |
CheckForStalledSocketGroups(); |
} |
} |
@@ -662,12 +627,12 @@ void ClientSocketPoolBaseHelper::RemoveConnectJob(const ConnectJob* job, |
connecting_socket_count_--; |
DCHECK(group); |
- DCHECK(ContainsKey(group->jobs, job)); |
- group->jobs.erase(job); |
+ DCHECK(ContainsKey(group->jobs(), job)); |
+ group->RemoveJob(job); |
// If we've got no more jobs for this group, then we no longer need a |
// backup job either. |
- if (group->jobs.empty()) |
+ if (group->jobs().empty()) |
group->CleanupBackupJob(); |
DCHECK(job); |
@@ -676,20 +641,21 @@ void ClientSocketPoolBaseHelper::RemoveConnectJob(const ConnectJob* job, |
void ClientSocketPoolBaseHelper::OnAvailableSocketSlot( |
const std::string& group_name, Group* group) { |
- if (!group->pending_requests.empty()) |
+ if (!group->pending_requests().empty()) |
ProcessPendingRequest(group_name, group); |
if (group->IsEmpty()) |
- group_map_.erase(group_name); |
+ RemoveGroup(group_name); |
} |
void ClientSocketPoolBaseHelper::ProcessPendingRequest( |
const std::string& group_name, Group* group) { |
int rv = RequestSocketInternal(group_name, |
- *group->pending_requests.begin()); |
+ *group->pending_requests().begin()); |
if (rv != ERR_IO_PENDING) { |
scoped_ptr<const Request> request(RemoveRequestFromQueue( |
- group->pending_requests.begin(), &group->pending_requests)); |
+ group->mutable_pending_requests()->begin(), |
+ group->mutable_pending_requests())); |
scoped_refptr<NetLog::EventParameters> params; |
if (rv != OK) |
@@ -725,7 +691,7 @@ void ClientSocketPoolBaseHelper::HandOutSocket( |
"source_dependency", socket->NetLog().source())); |
handed_out_socket_count_++; |
- group->active_socket_count++; |
+ group->IncrementActiveSocketCount(); |
} |
void ClientSocketPoolBaseHelper::AddIdleSocket( |
@@ -736,26 +702,19 @@ void ClientSocketPoolBaseHelper::AddIdleSocket( |
idle_socket.start_time = base::TimeTicks::Now(); |
idle_socket.used = used; |
- group->idle_sockets.push_back(idle_socket); |
+ group->mutable_idle_sockets()->push_back(idle_socket); |
IncrementIdleCount(); |
} |
void ClientSocketPoolBaseHelper::CancelAllConnectJobs() { |
- for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { |
- Group& group = i->second; |
- connecting_socket_count_ -= group.jobs.size(); |
- STLDeleteElements(&group.jobs); |
- |
- if (group.backup_task) { |
- group.backup_task->Cancel(); |
- group.backup_task = NULL; |
- } |
+ for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { |
+ Group* group = i->second; |
+ connecting_socket_count_ -= group->jobs().size(); |
+ group->RemoveAllJobs(); |
// Delete group if no longer needed. |
- if (group.IsEmpty()) { |
- group_map_.erase(i++); |
- } else { |
- ++i; |
+ if (group->IsEmpty()) { |
+ RemoveGroup(i); |
} |
} |
} |
@@ -775,15 +734,16 @@ void ClientSocketPoolBaseHelper::CloseOneIdleSocket() { |
CHECK_GT(idle_socket_count(), 0); |
for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { |
- Group& group = i->second; |
+ Group* group = i->second; |
- if (!group.idle_sockets.empty()) { |
- std::deque<IdleSocket>::iterator j = group.idle_sockets.begin(); |
+ if (!group->idle_sockets().empty()) { |
+ std::deque<IdleSocket>::iterator j = |
+ group->mutable_idle_sockets()->begin(); |
delete j->socket; |
- group.idle_sockets.erase(j); |
+ group->mutable_idle_sockets()->erase(j); |
DecrementIdleCount(); |
- if (group.IsEmpty()) |
- group_map_.erase(i); |
+ if (group->IsEmpty()) |
+ RemoveGroup(i); |
return; |
} |
@@ -819,6 +779,66 @@ void ClientSocketPoolBaseHelper::InvokeUserCallback( |
callback->Run(result); |
} |
+ClientSocketPoolBaseHelper::Group::Group() |
+ : active_socket_count_(0), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {} |
+ |
+ClientSocketPoolBaseHelper::Group::~Group() { |
+ CleanupBackupJob(); |
+} |
+ |
+void ClientSocketPoolBaseHelper::Group::StartBackupSocketTimer( |
+ const std::string& group_name, |
+ ClientSocketPoolBaseHelper* pool) { |
+ // Only allow one timer pending to create a backup socket. |
+ if (!method_factory_.empty()) |
+ return; |
+ |
+ MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ method_factory_.NewRunnableMethod( |
+ &Group::OnBackupSocketTimerFired, group_name, pool), |
+ pool->ConnectRetryIntervalMs()); |
+} |
+ |
+void ClientSocketPoolBaseHelper::Group::OnBackupSocketTimerFired( |
+ std::string group_name, |
+ ClientSocketPoolBaseHelper* pool) { |
+ // If there are no more jobs pending, there is no work to do. |
+ // If we've done our cleanups correctly, this should not happen. |
+ if (jobs_.empty()) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ |
+ // If our backup job is waiting on DNS, or if we can't create any sockets |
+ // right now due to limits, just reset the timer. |
+ if (pool->ReachedMaxSocketsLimit() || |
+ !HasAvailableSocketSlot(pool->max_sockets_per_group_) || |
+ (*jobs_.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) { |
+ StartBackupSocketTimer(group_name, pool); |
+ return; |
+ } |
+ |
+ ConnectJob* backup_job = pool->connect_job_factory_->NewConnectJob( |
+ group_name, **pending_requests_.begin(), pool); |
+ backup_job->net_log().AddEvent(NetLog::TYPE_SOCKET_BACKUP_CREATED, NULL); |
+ SIMPLE_STATS_COUNTER("socket.backup_created"); |
+ int rv = backup_job->Connect(); |
+ pool->connecting_socket_count_++; |
+ AddJob(backup_job); |
+ if (rv != ERR_IO_PENDING) |
+ pool->OnConnectJobComplete(rv, backup_job); |
+} |
+ |
+void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { |
+ // Delete active jobs. |
+ STLDeleteElements(&jobs_); |
+ |
+ // Cancel pending backup job. |
+ method_factory_.RevokeAll(); |
+} |
+ |
} // namespace internal |
} // namespace net |