summaryrefslogtreecommitdiffstats
path: root/net/websockets
diff options
context:
space:
mode:
Diffstat (limited to 'net/websockets')
-rw-r--r--net/websockets/websocket_throttle.cc16
-rw-r--r--net/websockets/websocket_throttle_unittest.cc25
2 files changed, 41 insertions, 0 deletions
diff --git a/net/websockets/websocket_throttle.cc b/net/websockets/websocket_throttle.cc
index e2e98c3..9e33cad 100644
--- a/net/websockets/websocket_throttle.cc
+++ b/net/websockets/websocket_throttle.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/hash_tables.h"
#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "base/singleton.h"
@@ -53,10 +54,17 @@ WebSocketThrottle::~WebSocketThrottle() {
void WebSocketThrottle::PutInQueue(WebSocketJob* job) {
queue_.push_back(job);
const AddressList& address_list = job->address_list();
+ base::hash_set<std::string> address_set;
for (const struct addrinfo* addrinfo = address_list.head();
addrinfo != NULL;
addrinfo = addrinfo->ai_next) {
std::string addrkey = AddrinfoToHashkey(addrinfo);
+
+ // If |addrkey| is already processed, don't do it again.
+ if (address_set.find(addrkey) != address_set.end())
+ continue;
+ address_set.insert(addrkey);
+
ConnectingAddressMap::iterator iter = addr_map_.find(addrkey);
if (iter == addr_map_.end()) {
ConnectingQueue* queue = new ConnectingQueue();
@@ -65,6 +73,7 @@ void WebSocketThrottle::PutInQueue(WebSocketJob* job) {
} else {
iter->second->push_back(job);
job->SetWaiting();
+ DLOG(INFO) << "Waiting on " << addrkey;
}
}
}
@@ -83,12 +92,19 @@ void WebSocketThrottle::RemoveFromQueue(WebSocketJob* job) {
if (!in_queue)
return;
const AddressList& address_list = job->address_list();
+ base::hash_set<std::string> address_set;
for (const struct addrinfo* addrinfo = address_list.head();
addrinfo != NULL;
addrinfo = addrinfo->ai_next) {
std::string addrkey = AddrinfoToHashkey(addrinfo);
+ // If |addrkey| is already processed, don't do it again.
+ if (address_set.find(addrkey) != address_set.end())
+ continue;
+ address_set.insert(addrkey);
+
ConnectingAddressMap::iterator iter = addr_map_.find(addrkey);
DCHECK(iter != addr_map_.end());
+
ConnectingQueue* queue = iter->second;
// Job may not be front of queue when job is closed early while waiting.
for (ConnectingQueue::iterator iter = queue->begin();
diff --git a/net/websockets/websocket_throttle_unittest.cc b/net/websockets/websocket_throttle_unittest.cc
index 91d588f..6c0dfbb 100644
--- a/net/websockets/websocket_throttle_unittest.cc
+++ b/net/websockets/websocket_throttle_unittest.cc
@@ -279,4 +279,29 @@ TEST_F(WebSocketThrottleTest, Throttle) {
MessageLoopForIO::current()->RunAllPending();
}
+TEST_F(WebSocketThrottleTest, NoThrottleForDuplicateAddress) {
+ DummySocketStreamDelegate delegate;
+
+ // For localhost: 127.0.0.1, 127.0.0.1
+ struct addrinfo* addr = AddAddr(127, 0, 0, 1, NULL);
+ addr = AddAddr(127, 0, 0, 1, addr);
+ scoped_refptr<WebSocketJob> w1 = new WebSocketJob(&delegate);
+ scoped_refptr<SocketStream> s1 =
+ new SocketStream(GURL("ws://localhost/"), w1.get());
+ w1->InitSocketStream(s1.get());
+ WebSocketThrottleTest::MockSocketStreamConnect(s1, addr);
+ DeleteAddrInfo(addr);
+
+ DLOG(INFO) << "socket1";
+ TestCompletionCallback callback_s1;
+ // Trying to open connection to localhost will start without wait.
+ EXPECT_EQ(OK, w1->OnStartOpenConnection(s1, &callback_s1));
+
+ DLOG(INFO) << "socket1 close";
+ w1->OnClose(s1.get());
+ s1->DetachDelegate();
+ DLOG(INFO) << "Done";
+ MessageLoopForIO::current()->RunAllPending();
+}
+
}