Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "net/socket/client_socket_pool_base.h" | 5 #include "net/socket/client_socket_pool_base.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 } | 200 } |
| 201 | 201 |
| 202 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { | 202 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { |
| 203 // Clean up any idle sockets and pending connect jobs. Assert that we have no | 203 // Clean up any idle sockets and pending connect jobs. Assert that we have no |
| 204 // remaining active sockets or pending requests. They should have all been | 204 // remaining active sockets or pending requests. They should have all been |
| 205 // cleaned up prior to |this| being destroyed. | 205 // cleaned up prior to |this| being destroyed. |
| 206 Flush(); | 206 Flush(); |
| 207 DCHECK(group_map_.empty()); | 207 DCHECK(group_map_.empty()); |
| 208 DCHECK(pending_callback_map_.empty()); | 208 DCHECK(pending_callback_map_.empty()); |
| 209 DCHECK_EQ(0, connecting_socket_count_); | 209 DCHECK_EQ(0, connecting_socket_count_); |
| 210 DCHECK(higher_layer_pools_.empty()); | |
|
mmenke
2012/03/14 14:44:48
Perhaps this should be a CHECK. It'll most likely
Ryan Hamilton
2012/03/15 21:44:31
Done.
| |
| 210 | 211 |
| 211 NetworkChangeNotifier::RemoveIPAddressObserver(this); | 212 NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 212 } | 213 } |
| 213 | 214 |
| 214 ClientSocketPoolBaseHelper::CallbackResultPair::~CallbackResultPair() {} | 215 ClientSocketPoolBaseHelper::CallbackResultPair::~CallbackResultPair() {} |
| 215 | 216 |
| 216 // InsertRequestIntoQueue inserts the request into the queue based on | 217 // InsertRequestIntoQueue inserts the request into the queue based on |
| 217 // priority. Highest priorities are closest to the front. Older requests are | 218 // priority. Highest priorities are closest to the front. Older requests are |
| 218 // prioritized over requests of equal priority. | 219 // prioritized over requests of equal priority. |
| 219 // | 220 // |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 231 ClientSocketPoolBaseHelper::RemoveRequestFromQueue( | 232 ClientSocketPoolBaseHelper::RemoveRequestFromQueue( |
| 232 const RequestQueue::iterator& it, Group* group) { | 233 const RequestQueue::iterator& it, Group* group) { |
| 233 const Request* req = *it; | 234 const Request* req = *it; |
| 234 group->mutable_pending_requests()->erase(it); | 235 group->mutable_pending_requests()->erase(it); |
| 235 // If there are no more requests, we kill the backup timer. | 236 // If there are no more requests, we kill the backup timer. |
| 236 if (group->pending_requests().empty()) | 237 if (group->pending_requests().empty()) |
| 237 group->CleanupBackupJob(); | 238 group->CleanupBackupJob(); |
| 238 return req; | 239 return req; |
| 239 } | 240 } |
| 240 | 241 |
| 242 void ClientSocketPoolBaseHelper::AddLayeredPool(LayeredPool* pool) { | |
| 243 CHECK(pool); | |
| 244 CHECK(!ContainsKey(higher_layer_pools_, pool)); | |
| 245 higher_layer_pools_.insert(pool); | |
| 246 } | |
| 247 | |
| 248 void ClientSocketPoolBaseHelper::RemoveLayeredPool(LayeredPool* pool) { | |
| 249 CHECK(pool); | |
| 250 CHECK(ContainsKey(higher_layer_pools_, pool)); | |
| 251 higher_layer_pools_.erase(pool); | |
| 252 } | |
| 253 | |
| 241 int ClientSocketPoolBaseHelper::RequestSocket( | 254 int ClientSocketPoolBaseHelper::RequestSocket( |
| 242 const std::string& group_name, | 255 const std::string& group_name, |
| 243 const Request* request) { | 256 const Request* request) { |
| 244 CHECK(!request->callback().is_null()); | 257 CHECK(!request->callback().is_null()); |
| 245 CHECK(request->handle()); | 258 CHECK(request->handle()); |
| 246 | 259 |
| 247 // Cleanup any timed-out idle sockets if no timer is used. | 260 // Cleanup any timed-out idle sockets if no timer is used. |
| 248 if (!use_cleanup_timer_) | 261 if (!use_cleanup_timer_) |
| 249 CleanupIdleSockets(false); | 262 CleanupIdleSockets(false); |
| 250 | 263 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 if (AssignIdleSocketToGroup(request, group)) | 342 if (AssignIdleSocketToGroup(request, group)) |
| 330 return OK; | 343 return OK; |
| 331 } | 344 } |
| 332 | 345 |
| 333 if (!preconnecting && group->TryToUsePreconnectConnectJob()) | 346 if (!preconnecting && group->TryToUsePreconnectConnectJob()) |
| 334 return ERR_IO_PENDING; | 347 return ERR_IO_PENDING; |
| 335 | 348 |
| 336 // Can we make another active socket now? | 349 // Can we make another active socket now? |
| 337 if (!group->HasAvailableSocketSlot(max_sockets_per_group_) && | 350 if (!group->HasAvailableSocketSlot(max_sockets_per_group_) && |
| 338 !request->ignore_limits()) { | 351 !request->ignore_limits()) { |
| 352 // TODO(willchan): Consider whether or not we need to close a socket in a | |
| 353 // higher layered group. I don't think this makes sense since we would just | |
| 354 // reuse that socket then if we needed one and wouldn't make it down to this | |
| 355 // layer. | |
| 339 request->net_log().AddEvent( | 356 request->net_log().AddEvent( |
| 340 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP, NULL); | 357 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP, NULL); |
| 341 return ERR_IO_PENDING; | 358 return ERR_IO_PENDING; |
| 342 } | 359 } |
| 343 | 360 |
| 344 if (ReachedMaxSocketsLimit() && !request->ignore_limits()) { | 361 if (ReachedMaxSocketsLimit() && !request->ignore_limits()) { |
| 345 if (idle_socket_count() > 0) { | 362 if (idle_socket_count() > 0) { |
|
mmenke
2012/03/14 14:44:48
Comment for the future: Wonder if we really need
Ryan Hamilton
2012/03/15 21:44:31
Added your comment as a NOTE
| |
| 363 // There's an idle socket in this pool. Either that's because there's | |
| 364 // still one in this group, but we got here due to preconnecting bypassing | |
| 365 // idle sockets, or because there's an idle socket in another group. | |
| 346 bool closed = CloseOneIdleSocketExceptInGroup(group); | 366 bool closed = CloseOneIdleSocketExceptInGroup(group); |
| 347 if (preconnecting && !closed) | 367 if (preconnecting && !closed) |
| 348 return ERR_PRECONNECT_MAX_SOCKET_LIMIT; | 368 return ERR_PRECONNECT_MAX_SOCKET_LIMIT; |
| 349 } else { | 369 } else { |
| 350 // We could check if we really have a stalled group here, but it requires | 370 do { |
| 351 // a scan of all groups, so just flip a flag here, and do the check later. | 371 if (!CloseOneIdleConnectionInLayeredPool()) { |
| 352 request->net_log().AddEvent( | 372 // We could check if we really have a stalled group here, but it |
| 353 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS, NULL); | 373 // requires a scan of all groups, so just flip a flag here, and do |
| 354 return ERR_IO_PENDING; | 374 // the check later. |
| 375 request->net_log().AddEvent( | |
| 376 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS, NULL); | |
| 377 return ERR_IO_PENDING; | |
| 378 } | |
| 379 } while (ReachedMaxSocketsLimit()); | |
| 380 | |
| 381 // It is possible that CloseOneIdleConnectionInLayeredPool() has deleted | |
| 382 // our Group (see http://crbug.com/109876), so look it up again | |
| 383 // to be safe. | |
| 384 group = GetOrCreateGroup(group_name); | |
| 355 } | 385 } |
| 356 } | 386 } |
| 357 | 387 |
| 358 // We couldn't find a socket to reuse, so allocate and connect a new one. | 388 // We couldn't find a socket to reuse, and there's space to allocate one, |
| 389 // so allocate and connect a new one. | |
| 359 scoped_ptr<ConnectJob> connect_job( | 390 scoped_ptr<ConnectJob> connect_job( |
| 360 connect_job_factory_->NewConnectJob(group_name, *request, this)); | 391 connect_job_factory_->NewConnectJob(group_name, *request, this)); |
| 361 | 392 |
| 362 connect_job->Initialize(preconnecting); | 393 connect_job->Initialize(preconnecting); |
| 363 int rv = connect_job->Connect(); | 394 int rv = connect_job->Connect(); |
| 364 if (rv == OK) { | 395 if (rv == OK) { |
| 365 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); | 396 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); |
| 366 if (!preconnecting) { | 397 if (!preconnecting) { |
| 367 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, | 398 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, |
| 368 handle, base::TimeDelta(), group, request->net_log()); | 399 handle, base::TimeDelta(), group, request->net_log()); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 757 // Add it to the idle list. | 788 // Add it to the idle list. |
| 758 AddIdleSocket(socket, group); | 789 AddIdleSocket(socket, group); |
| 759 OnAvailableSocketSlot(group_name, group); | 790 OnAvailableSocketSlot(group_name, group); |
| 760 } else { | 791 } else { |
| 761 delete socket; | 792 delete socket; |
| 762 } | 793 } |
| 763 | 794 |
| 764 CheckForStalledSocketGroups(); | 795 CheckForStalledSocketGroups(); |
| 765 } | 796 } |
| 766 | 797 |
| 767 void ClientSocketPoolBaseHelper::CheckForStalledSocketGroups() { | 798 void ClientSocketPoolBaseHelper::CheckForStalledSocketGroups() { |
|
mmenke
2012/03/14 14:44:48
Should we check if higher level pools are stalled
Ryan Hamilton
2012/03/15 21:44:31
Possibly, though I think this CL is complicated en
| |
| 768 // If we have idle sockets, see if we can give one to the top-stalled group. | 799 // If we have idle sockets, see if we can give one to the top-stalled group. |
| 769 std::string top_group_name; | 800 std::string top_group_name; |
| 770 Group* top_group = NULL; | 801 Group* top_group = NULL; |
| 771 if (!FindTopStalledGroup(&top_group, &top_group_name)) | 802 if (!FindTopStalledGroup(&top_group, &top_group_name)) |
| 772 return; | 803 return; |
| 773 | 804 |
| 774 if (ReachedMaxSocketsLimit()) { | 805 if (ReachedMaxSocketsLimit()) { |
| 775 if (idle_socket_count() > 0) { | 806 if (idle_socket_count() > 0) { |
| 776 CloseOneIdleSocket(); | 807 CloseOneIdleSocket(); |
| 777 } else { | 808 } else { |
| 778 // We can't activate more sockets since we're already at our global | 809 // We can't activate more sockets since we're already at our global |
| 779 // limit. | 810 // limit. |
| 780 return; | 811 return; |
| 781 } | 812 } |
| 782 } | 813 } |
| 783 | 814 |
| 784 // Note: we don't loop on waking stalled groups. If the stalled group is at | 815 // Note: we don't loop on waking stalled groups. If the stalled group is at |
| 785 // its limit, may be left with other stalled groups that could be | 816 // its limit, may be left with other stalled groups that could be |
| 786 // woken. This isn't optimal, but there is no starvation, so to avoid | 817 // woken. This isn't optimal, but there is no starvation, so to avoid |
| 787 // the looping we leave it at this. | 818 // the looping we leave it at this. |
| 788 OnAvailableSocketSlot(top_group_name, top_group); | 819 OnAvailableSocketSlot(top_group_name, top_group); |
| 789 } | 820 } |
| 790 | 821 |
| 791 // Search for the highest priority pending request, amongst the groups that | 822 // Search for the highest priority pending request, amongst the groups that |
| 792 // are not at the |max_sockets_per_group_| limit. Note: for requests with | 823 // are not at the |max_sockets_per_group_| limit. Note: for requests with |
| 793 // the same priority, the winner is based on group hash ordering (and not | 824 // the same priority, the winner is based on group hash ordering (and not |
| 794 // insertion order). | 825 // insertion order). |
| 795 bool ClientSocketPoolBaseHelper::FindTopStalledGroup(Group** group, | 826 bool ClientSocketPoolBaseHelper::FindTopStalledGroup( |
| 796 std::string* group_name) { | 827 Group** group, |
| 828 std::string* group_name) const { | |
| 829 CHECK((group && group_name) || (!group && !group_name)); | |
|
mmenke
2012/03/14 14:44:48
Allowing |group| and |group_name| to be NULL shoul
Ryan Hamilton
2012/03/15 21:44:31
Done.
| |
| 797 Group* top_group = NULL; | 830 Group* top_group = NULL; |
| 798 const std::string* top_group_name = NULL; | 831 const std::string* top_group_name = NULL; |
| 799 bool has_stalled_group = false; | 832 bool has_stalled_group = false; |
| 800 for (GroupMap::iterator i = group_map_.begin(); | 833 for (GroupMap::const_iterator i = group_map_.begin(); |
| 801 i != group_map_.end(); ++i) { | 834 i != group_map_.end(); ++i) { |
| 802 Group* curr_group = i->second; | 835 Group* curr_group = i->second; |
| 803 const RequestQueue& queue = curr_group->pending_requests(); | 836 const RequestQueue& queue = curr_group->pending_requests(); |
| 804 if (queue.empty()) | 837 if (queue.empty()) |
| 805 continue; | 838 continue; |
| 806 if (curr_group->IsStalled(max_sockets_per_group_)) { | 839 if (curr_group->IsStalled(max_sockets_per_group_)) { |
| 840 if (!group) | |
| 841 return true; | |
| 807 has_stalled_group = true; | 842 has_stalled_group = true; |
| 808 bool has_higher_priority = !top_group || | 843 bool has_higher_priority = !top_group || |
| 809 curr_group->TopPendingPriority() < top_group->TopPendingPriority(); | 844 curr_group->TopPendingPriority() < top_group->TopPendingPriority(); |
| 810 if (has_higher_priority) { | 845 if (has_higher_priority) { |
| 811 top_group = curr_group; | 846 top_group = curr_group; |
| 812 top_group_name = &i->first; | 847 top_group_name = &i->first; |
| 813 } | 848 } |
| 814 } | 849 } |
| 815 } | 850 } |
| 816 | 851 |
| 817 if (top_group) { | 852 if (top_group) { |
| 853 CHECK(group); | |
| 818 *group = top_group; | 854 *group = top_group; |
| 819 *group_name = *top_group_name; | 855 *group_name = *top_group_name; |
| 856 } else { | |
| 857 CHECK(!has_stalled_group); | |
| 820 } | 858 } |
| 821 return has_stalled_group; | 859 return has_stalled_group; |
| 822 } | 860 } |
| 823 | 861 |
| 824 void ClientSocketPoolBaseHelper::OnConnectJobComplete( | 862 void ClientSocketPoolBaseHelper::OnConnectJobComplete( |
| 825 int result, ConnectJob* job) { | 863 int result, ConnectJob* job) { |
| 826 DCHECK_NE(ERR_IO_PENDING, result); | 864 DCHECK_NE(ERR_IO_PENDING, result); |
| 827 const std::string group_name = job->group_name(); | 865 const std::string group_name = job->group_name(); |
| 828 GroupMap::iterator group_it = group_map_.find(group_name); | 866 GroupMap::iterator group_it = group_map_.find(group_name); |
| 829 CHECK(group_it != group_map_.end()); | 867 CHECK(group_it != group_map_.end()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 Flush(); | 920 Flush(); |
| 883 } | 921 } |
| 884 | 922 |
| 885 void ClientSocketPoolBaseHelper::Flush() { | 923 void ClientSocketPoolBaseHelper::Flush() { |
| 886 pool_generation_number_++; | 924 pool_generation_number_++; |
| 887 CancelAllConnectJobs(); | 925 CancelAllConnectJobs(); |
| 888 CloseIdleSockets(); | 926 CloseIdleSockets(); |
| 889 AbortAllRequests(); | 927 AbortAllRequests(); |
| 890 } | 928 } |
| 891 | 929 |
| 930 bool ClientSocketPoolBaseHelper::IsStalled() const { | |
| 931 if ((handed_out_socket_count_ + connecting_socket_count_) < max_sockets_) | |
| 932 return false; | |
| 933 for (GroupMap::const_iterator it = group_map_.begin(); | |
| 934 it != group_map_.end(); it++) { | |
| 935 if (it->second->IsStalled(max_sockets_per_group_)) | |
|
mmenke
2012/03/14 14:44:48
I don't think this is correct. Either the descrip
Ryan Hamilton
2012/03/15 21:44:31
Will and I discussed this in great detail yesterda
| |
| 936 return true; | |
| 937 } | |
| 938 return false; | |
| 939 } | |
| 940 | |
| 892 void ClientSocketPoolBaseHelper::RemoveConnectJob(ConnectJob* job, | 941 void ClientSocketPoolBaseHelper::RemoveConnectJob(ConnectJob* job, |
| 893 Group* group) { | 942 Group* group) { |
| 894 CHECK_GT(connecting_socket_count_, 0); | 943 CHECK_GT(connecting_socket_count_, 0); |
| 895 connecting_socket_count_--; | 944 connecting_socket_count_--; |
| 896 | 945 |
| 897 DCHECK(group); | 946 DCHECK(group); |
| 898 DCHECK(ContainsKey(group->jobs(), job)); | 947 DCHECK(ContainsKey(group->jobs(), job)); |
| 899 group->RemoveJob(job); | 948 group->RemoveJob(job); |
| 900 | 949 |
| 901 // If we've got no more jobs for this group, then we no longer need a | 950 // If we've got no more jobs for this group, then we no longer need a |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1018 // Each connecting socket will eventually connect and be handed out. | 1067 // Each connecting socket will eventually connect and be handed out. |
| 1019 int total = handed_out_socket_count_ + connecting_socket_count_ + | 1068 int total = handed_out_socket_count_ + connecting_socket_count_ + |
| 1020 idle_socket_count(); | 1069 idle_socket_count(); |
| 1021 // There can be more sockets than the limit since some requests can ignore | 1070 // There can be more sockets than the limit since some requests can ignore |
| 1022 // the limit | 1071 // the limit |
| 1023 if (total < max_sockets_) | 1072 if (total < max_sockets_) |
| 1024 return false; | 1073 return false; |
| 1025 return true; | 1074 return true; |
| 1026 } | 1075 } |
| 1027 | 1076 |
| 1028 void ClientSocketPoolBaseHelper::CloseOneIdleSocket() { | 1077 bool ClientSocketPoolBaseHelper::CloseOneIdleSocket() { |
| 1029 CloseOneIdleSocketExceptInGroup(NULL); | 1078 if (idle_socket_count() == 0) |
| 1079 return false; | |
| 1080 return CloseOneIdleSocketExceptInGroup(NULL); | |
| 1030 } | 1081 } |
| 1031 | 1082 |
| 1032 bool ClientSocketPoolBaseHelper::CloseOneIdleSocketExceptInGroup( | 1083 bool ClientSocketPoolBaseHelper::CloseOneIdleSocketExceptInGroup( |
| 1033 const Group* exception_group) { | 1084 const Group* exception_group) { |
| 1034 CHECK_GT(idle_socket_count(), 0); | 1085 CHECK_GT(idle_socket_count(), 0); |
| 1035 | 1086 |
| 1036 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { | 1087 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { |
| 1037 Group* group = i->second; | 1088 Group* group = i->second; |
| 1038 if (exception_group == group) | 1089 if (exception_group == group) |
| 1039 continue; | 1090 continue; |
| 1040 std::list<IdleSocket>* idle_sockets = group->mutable_idle_sockets(); | 1091 std::list<IdleSocket>* idle_sockets = group->mutable_idle_sockets(); |
| 1041 | 1092 |
| 1042 if (!idle_sockets->empty()) { | 1093 if (!idle_sockets->empty()) { |
| 1043 delete idle_sockets->front().socket; | 1094 delete idle_sockets->front().socket; |
| 1044 idle_sockets->pop_front(); | 1095 idle_sockets->pop_front(); |
| 1045 DecrementIdleCount(); | 1096 DecrementIdleCount(); |
| 1046 if (group->IsEmpty()) | 1097 if (group->IsEmpty()) |
| 1047 RemoveGroup(i); | 1098 RemoveGroup(i); |
| 1048 | 1099 |
| 1049 return true; | 1100 return true; |
| 1050 } | 1101 } |
| 1051 } | 1102 } |
| 1052 | 1103 |
| 1053 if (!exception_group) | |
| 1054 LOG(DFATAL) << "No idle socket found to close!."; | |
| 1055 | |
| 1056 return false; | 1104 return false; |
| 1057 } | 1105 } |
| 1058 | 1106 |
| 1107 bool ClientSocketPoolBaseHelper::CloseOneIdleConnectionInLayeredPool() { | |
| 1108 // This pool doesn't have any idle sockets. It's possible that a pool at a | |
| 1109 // higher layer is holding one of this sockets active, but it's actually idle. | |
| 1110 // Query the higher layers. | |
| 1111 for (std::set<LayeredPool*>::const_iterator it = higher_layer_pools_.begin(); | |
| 1112 it != higher_layer_pools_.end(); ++it) { | |
| 1113 if ((*it)->CloseOneIdleConnection()) | |
| 1114 return true; | |
| 1115 } | |
| 1116 return false; | |
| 1117 } | |
| 1118 | |
| 1059 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( | 1119 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( |
| 1060 ClientSocketHandle* handle, const CompletionCallback& callback, int rv) { | 1120 ClientSocketHandle* handle, const CompletionCallback& callback, int rv) { |
| 1061 CHECK(!ContainsKey(pending_callback_map_, handle)); | 1121 CHECK(!ContainsKey(pending_callback_map_, handle)); |
| 1062 pending_callback_map_[handle] = CallbackResultPair(callback, rv); | 1122 pending_callback_map_[handle] = CallbackResultPair(callback, rv); |
| 1063 MessageLoop::current()->PostTask( | 1123 MessageLoop::current()->PostTask( |
| 1064 FROM_HERE, | 1124 FROM_HERE, |
| 1065 base::Bind(&ClientSocketPoolBaseHelper::InvokeUserCallback, | 1125 base::Bind(&ClientSocketPoolBaseHelper::InvokeUserCallback, |
| 1066 weak_factory_.GetWeakPtr(), handle)); | 1126 weak_factory_.GetWeakPtr(), handle)); |
| 1067 } | 1127 } |
| 1068 | 1128 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1152 // Delete active jobs. | 1212 // Delete active jobs. |
| 1153 STLDeleteElements(&jobs_); | 1213 STLDeleteElements(&jobs_); |
| 1154 | 1214 |
| 1155 // Cancel pending backup job. | 1215 // Cancel pending backup job. |
| 1156 weak_factory_.InvalidateWeakPtrs(); | 1216 weak_factory_.InvalidateWeakPtrs(); |
| 1157 } | 1217 } |
| 1158 | 1218 |
| 1159 } // namespace internal | 1219 } // namespace internal |
| 1160 | 1220 |
| 1161 } // namespace net | 1221 } // namespace net |
| OLD | NEW |