| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/websockets/websocket_throttle.h" | 5 #include "net/websockets/websocket_throttle.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/hash_tables.h" |
| 9 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 10 #include "base/ref_counted.h" | 11 #include "base/ref_counted.h" |
| 11 #include "base/singleton.h" | 12 #include "base/singleton.h" |
| 12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 13 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
| 14 #include "net/base/sys_addrinfo.h" | 15 #include "net/base/sys_addrinfo.h" |
| 15 #include "net/socket_stream/socket_stream.h" | 16 #include "net/socket_stream/socket_stream.h" |
| 16 #include "net/websockets/websocket_job.h" | 17 #include "net/websockets/websocket_job.h" |
| 17 | 18 |
| 18 namespace net { | 19 namespace net { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 46 } | 47 } |
| 47 | 48 |
| 48 WebSocketThrottle::~WebSocketThrottle() { | 49 WebSocketThrottle::~WebSocketThrottle() { |
| 49 DCHECK(queue_.empty()); | 50 DCHECK(queue_.empty()); |
| 50 DCHECK(addr_map_.empty()); | 51 DCHECK(addr_map_.empty()); |
| 51 } | 52 } |
| 52 | 53 |
| 53 void WebSocketThrottle::PutInQueue(WebSocketJob* job) { | 54 void WebSocketThrottle::PutInQueue(WebSocketJob* job) { |
| 54 queue_.push_back(job); | 55 queue_.push_back(job); |
| 55 const AddressList& address_list = job->address_list(); | 56 const AddressList& address_list = job->address_list(); |
| 57 base::hash_set<std::string> address_set; |
| 56 for (const struct addrinfo* addrinfo = address_list.head(); | 58 for (const struct addrinfo* addrinfo = address_list.head(); |
| 57 addrinfo != NULL; | 59 addrinfo != NULL; |
| 58 addrinfo = addrinfo->ai_next) { | 60 addrinfo = addrinfo->ai_next) { |
| 59 std::string addrkey = AddrinfoToHashkey(addrinfo); | 61 std::string addrkey = AddrinfoToHashkey(addrinfo); |
| 62 |
| 63 // If |addrkey| is already processed, don't do it again. |
| 64 if (address_set.find(addrkey) != address_set.end()) |
| 65 continue; |
| 66 address_set.insert(addrkey); |
| 67 |
| 60 ConnectingAddressMap::iterator iter = addr_map_.find(addrkey); | 68 ConnectingAddressMap::iterator iter = addr_map_.find(addrkey); |
| 61 if (iter == addr_map_.end()) { | 69 if (iter == addr_map_.end()) { |
| 62 ConnectingQueue* queue = new ConnectingQueue(); | 70 ConnectingQueue* queue = new ConnectingQueue(); |
| 63 queue->push_back(job); | 71 queue->push_back(job); |
| 64 addr_map_[addrkey] = queue; | 72 addr_map_[addrkey] = queue; |
| 65 } else { | 73 } else { |
| 66 iter->second->push_back(job); | 74 iter->second->push_back(job); |
| 67 job->SetWaiting(); | 75 job->SetWaiting(); |
| 76 DLOG(INFO) << "Waiting on " << addrkey; |
| 68 } | 77 } |
| 69 } | 78 } |
| 70 } | 79 } |
| 71 | 80 |
| 72 void WebSocketThrottle::RemoveFromQueue(WebSocketJob* job) { | 81 void WebSocketThrottle::RemoveFromQueue(WebSocketJob* job) { |
| 73 bool in_queue = false; | 82 bool in_queue = false; |
| 74 for (ConnectingQueue::iterator iter = queue_.begin(); | 83 for (ConnectingQueue::iterator iter = queue_.begin(); |
| 75 iter != queue_.end(); | 84 iter != queue_.end(); |
| 76 ++iter) { | 85 ++iter) { |
| 77 if (*iter == job) { | 86 if (*iter == job) { |
| 78 queue_.erase(iter); | 87 queue_.erase(iter); |
| 79 in_queue = true; | 88 in_queue = true; |
| 80 break; | 89 break; |
| 81 } | 90 } |
| 82 } | 91 } |
| 83 if (!in_queue) | 92 if (!in_queue) |
| 84 return; | 93 return; |
| 85 const AddressList& address_list = job->address_list(); | 94 const AddressList& address_list = job->address_list(); |
| 95 base::hash_set<std::string> address_set; |
| 86 for (const struct addrinfo* addrinfo = address_list.head(); | 96 for (const struct addrinfo* addrinfo = address_list.head(); |
| 87 addrinfo != NULL; | 97 addrinfo != NULL; |
| 88 addrinfo = addrinfo->ai_next) { | 98 addrinfo = addrinfo->ai_next) { |
| 89 std::string addrkey = AddrinfoToHashkey(addrinfo); | 99 std::string addrkey = AddrinfoToHashkey(addrinfo); |
| 100 // If |addrkey| is already processed, don't do it again. |
| 101 if (address_set.find(addrkey) != address_set.end()) |
| 102 continue; |
| 103 address_set.insert(addrkey); |
| 104 |
| 90 ConnectingAddressMap::iterator iter = addr_map_.find(addrkey); | 105 ConnectingAddressMap::iterator iter = addr_map_.find(addrkey); |
| 91 DCHECK(iter != addr_map_.end()); | 106 DCHECK(iter != addr_map_.end()); |
| 107 |
| 92 ConnectingQueue* queue = iter->second; | 108 ConnectingQueue* queue = iter->second; |
| 93 // Job may not be front of queue when job is closed early while waiting. | 109 // Job may not be front of queue when job is closed early while waiting. |
| 94 for (ConnectingQueue::iterator iter = queue->begin(); | 110 for (ConnectingQueue::iterator iter = queue->begin(); |
| 95 iter != queue->end(); | 111 iter != queue->end(); |
| 96 ++iter) { | 112 ++iter) { |
| 97 if (*iter == job) { | 113 if (*iter == job) { |
| 98 queue->erase(iter); | 114 queue->erase(iter); |
| 99 break; | 115 break; |
| 100 } | 116 } |
| 101 } | 117 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 127 should_wakeup = false; | 143 should_wakeup = false; |
| 128 break; | 144 break; |
| 129 } | 145 } |
| 130 } | 146 } |
| 131 if (should_wakeup) | 147 if (should_wakeup) |
| 132 job->Wakeup(); | 148 job->Wakeup(); |
| 133 } | 149 } |
| 134 } | 150 } |
| 135 | 151 |
| 136 } // namespace net | 152 } // namespace net |
| OLD | NEW |