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

Side by Side Diff: net/socket/tcp_client_socket_pool.cc

Issue 146037: Fix crash in ClientSocketPoolBase. (Closed)
Patch Set: Fix formatting. Created 11 years, 6 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
« no previous file with comments | « net/socket/tcp_client_socket_pool.h ('k') | net/socket/tcp_client_socket_pool_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/tcp_client_socket_pool.h" 5 #include "net/socket/tcp_client_socket_pool.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/field_trial.h" 8 #include "base/field_trial.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 return; 226 return;
227 } 227 }
228 } 228 }
229 229
230 // It's invalid to cancel a non-existent request. 230 // It's invalid to cancel a non-existent request.
231 CHECK(ContainsKey(group.connecting_requests, handle)); 231 CHECK(ContainsKey(group.connecting_requests, handle));
232 232
233 RequestMap::iterator map_it = group.connecting_requests.find(handle); 233 RequestMap::iterator map_it = group.connecting_requests.find(handle);
234 if (map_it != group.connecting_requests.end()) { 234 if (map_it != group.connecting_requests.end()) {
235 RemoveConnectingSocket(handle); 235 RemoveConnectingSocket(handle);
236
237 group.connecting_requests.erase(map_it); 236 group.connecting_requests.erase(map_it);
238 group.active_socket_count--; 237 RemoveActiveSocket(group_name, &group);
239
240 if (!group.pending_requests.empty()) {
241 ProcessPendingRequest(group_name, &group);
242 return; // |group| may be invalid after this, so return to be safe.
243 }
244
245 // Delete group if no longer needed.
246 if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
247 CHECK(group.pending_requests.empty());
248 CHECK(group.connecting_requests.empty());
249 group_map_.erase(group_name);
250 return; // |group| is invalid after this, so return to be safe.
251 }
252 } 238 }
253
254 CheckSocketCounts(group);
255 } 239 }
256 240
257 void ClientSocketPoolBase::ReleaseSocket(const std::string& group_name, 241 void ClientSocketPoolBase::ReleaseSocket(const std::string& group_name,
258 ClientSocket* socket) { 242 ClientSocket* socket) {
259 // Run this asynchronously to allow the caller to finish before we let 243 // Run this asynchronously to allow the caller to finish before we let
260 // another to begin doing work. This also avoids nasty recursion issues. 244 // another to begin doing work. This also avoids nasty recursion issues.
261 // NOTE: We cannot refer to the handle argument after this method returns. 245 // NOTE: We cannot refer to the handle argument after this method returns.
262 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 246 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
263 this, &ClientSocketPoolBase::DoReleaseSocket, group_name, socket)); 247 this, &ClientSocketPoolBase::DoReleaseSocket, group_name, socket));
264 } 248 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 void ClientSocketPoolBase::DoReleaseSocket(const std::string& group_name, 350 void ClientSocketPoolBase::DoReleaseSocket(const std::string& group_name,
367 ClientSocket* socket) { 351 ClientSocket* socket) {
368 GroupMap::iterator i = group_map_.find(group_name); 352 GroupMap::iterator i = group_map_.find(group_name);
369 CHECK(i != group_map_.end()); 353 CHECK(i != group_map_.end());
370 354
371 Group& group = i->second; 355 Group& group = i->second;
372 356
373 CHECK(group.active_socket_count > 0); 357 CHECK(group.active_socket_count > 0);
374 CheckSocketCounts(group); 358 CheckSocketCounts(group);
375 359
376 group.active_socket_count--;
377 group.sockets_handed_out_count--; 360 group.sockets_handed_out_count--;
378 361
379 const bool can_reuse = socket->IsConnectedAndIdle(); 362 const bool can_reuse = socket->IsConnectedAndIdle();
380 if (can_reuse) { 363 if (can_reuse) {
381 IdleSocket idle_socket; 364 IdleSocket idle_socket;
382 idle_socket.socket = socket; 365 idle_socket.socket = socket;
383 idle_socket.start_time = base::TimeTicks::Now(); 366 idle_socket.start_time = base::TimeTicks::Now();
384 367
385 group.idle_sockets.push_back(idle_socket); 368 group.idle_sockets.push_back(idle_socket);
386 IncrementIdleCount(); 369 IncrementIdleCount();
387 } else { 370 } else {
388 delete socket; 371 delete socket;
389 } 372 }
390 373
391 // Process one pending request. 374 RemoveActiveSocket(group_name, &group);
392 if (!group.pending_requests.empty()) {
393 ProcessPendingRequest(group_name, &group);
394 return;
395 }
396
397 // Delete group if no longer needed.
398 if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
399 CHECK(group.pending_requests.empty());
400 CHECK(group.connecting_requests.empty());
401 group_map_.erase(i);
402 } else {
403 CheckSocketCounts(group);
404 }
405 } 375 }
406 376
407 ClientSocketPoolBase::Request* ClientSocketPoolBase::GetConnectingRequest( 377 ClientSocketPoolBase::Request* ClientSocketPoolBase::GetConnectingRequest(
408 const std::string& group_name, const ClientSocketHandle* handle) { 378 const std::string& group_name, const ClientSocketHandle* handle) {
409 GroupMap::iterator group_it = group_map_.find(group_name); 379 GroupMap::iterator group_it = group_map_.find(group_name);
410 if (group_it == group_map_.end()) 380 if (group_it == group_map_.end())
411 return NULL; 381 return NULL;
412 382
413 Group& group = group_it->second; 383 Group& group = group_it->second;
414 384
(...skipping 19 matching lines...) Expand all
434 404
435 RequestMap* request_map = &group.connecting_requests; 405 RequestMap* request_map = &group.connecting_requests;
436 406
437 RequestMap::iterator it = request_map->find(handle); 407 RequestMap::iterator it = request_map->find(handle);
438 CHECK(it != request_map->end()); 408 CHECK(it != request_map->end());
439 Request request = it->second; 409 Request request = it->second;
440 request_map->erase(it); 410 request_map->erase(it);
441 DCHECK_EQ(request.handle, handle); 411 DCHECK_EQ(request.handle, handle);
442 412
443 if (deactivate) { 413 if (deactivate) {
444 group.active_socket_count--; 414 RemoveActiveSocket(group_name, &group);
445
446 // Delete group if no longer needed.
447 if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
448 DCHECK(group.pending_requests.empty());
449 DCHECK(group.connecting_requests.empty());
450 group_map_.erase(group_name);
451 } else {
452 CheckSocketCounts(group);
453 }
454 } else { 415 } else {
455 request.handle->set_socket(socket); 416 request.handle->set_socket(socket);
456 request.handle->set_is_reused(false); 417 request.handle->set_is_reused(false);
457 group.sockets_handed_out_count++; 418 group.sockets_handed_out_count++;
458 419
459 CheckSocketCounts(group); 420 CheckSocketCounts(group);
460 } 421 }
461 422
462 RemoveConnectingSocket(request.handle); 423 RemoveConnectingSocket(request.handle);
463 424
(...skipping 11 matching lines...) Expand all
475 } 436 }
476 437
477 void ClientSocketPoolBase::RemoveConnectingSocket( 438 void ClientSocketPoolBase::RemoveConnectingSocket(
478 const ClientSocketHandle* handle) { 439 const ClientSocketHandle* handle) {
479 ConnectingSocketMap::iterator it = connecting_socket_map_.find(handle); 440 ConnectingSocketMap::iterator it = connecting_socket_map_.find(handle);
480 CHECK(it != connecting_socket_map_.end()); 441 CHECK(it != connecting_socket_map_.end());
481 delete it->second; 442 delete it->second;
482 connecting_socket_map_.erase(it); 443 connecting_socket_map_.erase(it);
483 } 444 }
484 445
446 void ClientSocketPoolBase::RemoveActiveSocket(const std::string& group_name,
447 Group* group) {
448 group->active_socket_count--;
449
450 if (!group->pending_requests.empty()) {
451 ProcessPendingRequest(group_name, group);
452 // |group| may no longer be valid after this point. Be careful not to
453 // access it again.
454 } else if (group->active_socket_count == 0 && group->idle_sockets.empty()) {
455 // Delete |group| if no longer needed. |group| will no longer be valid.
456 DCHECK(group->connecting_requests.empty());
457 group_map_.erase(group_name);
458 } else {
459 CheckSocketCounts(*group);
460 }
461 }
462
485 void ClientSocketPoolBase::ProcessPendingRequest(const std::string& group_name, 463 void ClientSocketPoolBase::ProcessPendingRequest(const std::string& group_name,
486 Group* group) { 464 Group* group) {
487 Request r = group->pending_requests.front(); 465 Request r = group->pending_requests.front();
488 group->pending_requests.pop_front(); 466 group->pending_requests.pop_front();
489 467
490 int rv = RequestSocket( 468 int rv = RequestSocket(
491 group_name, r.resolve_info, r.priority, r.handle, r.callback); 469 group_name, r.resolve_info, r.priority, r.handle, r.callback);
492 470
493 // |group| may be invalid after RequestSocket. 471 // |group| may be invalid after RequestSocket.
494 472
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 const std::string& group_name) const { 524 const std::string& group_name) const {
547 return base_->IdleSocketCountInGroup(group_name); 525 return base_->IdleSocketCountInGroup(group_name);
548 } 526 }
549 527
550 LoadState TCPClientSocketPool::GetLoadState( 528 LoadState TCPClientSocketPool::GetLoadState(
551 const std::string& group_name, const ClientSocketHandle* handle) const { 529 const std::string& group_name, const ClientSocketHandle* handle) const {
552 return base_->GetLoadState(group_name, handle); 530 return base_->GetLoadState(group_name, handle);
553 } 531 }
554 532
555 } // namespace net 533 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/tcp_client_socket_pool.h ('k') | net/socket/tcp_client_socket_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698