1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/socket/websocket_endpoint_lock_manager.h"
9 #include "base/logging.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/net_log.h"
15 WebSocketEndpointLockManager::Waiter::~Waiter() {
22 WebSocketEndpointLockManager
* WebSocketEndpointLockManager::GetInstance() {
23 return Singleton
<WebSocketEndpointLockManager
>::get();
26 int WebSocketEndpointLockManager::LockEndpoint(const IPEndPoint
& endpoint
,
28 EndPointWaiterMap::value_type
insert_value(endpoint
, NULL
);
29 std::pair
<EndPointWaiterMap::iterator
, bool> rv
=
30 endpoint_waiter_map_
.insert(insert_value
);
32 DVLOG(3) << "Locking endpoint " << endpoint
.ToString();
33 rv
.first
->second
= new ConnectJobQueue
;
36 DVLOG(3) << "Waiting for endpoint " << endpoint
.ToString();
37 rv
.first
->second
->Append(waiter
);
38 return ERR_IO_PENDING
;
41 void WebSocketEndpointLockManager::RememberSocket(StreamSocket
* socket
,
42 const IPEndPoint
& endpoint
) {
43 bool inserted
= socket_endpoint_map_
.insert(SocketEndPointMap::value_type(
44 socket
, endpoint
)).second
;
46 DCHECK(endpoint_waiter_map_
.find(endpoint
) != endpoint_waiter_map_
.end());
47 DVLOG(3) << "Remembered (StreamSocket*)" << socket
<< " for "
48 << endpoint
.ToString() << " (" << socket_endpoint_map_
.size()
49 << " sockets remembered)";
52 void WebSocketEndpointLockManager::UnlockSocket(StreamSocket
* socket
) {
53 SocketEndPointMap::iterator socket_it
= socket_endpoint_map_
.find(socket
);
54 if (socket_it
== socket_endpoint_map_
.end()) {
55 DVLOG(3) << "Ignoring request to unlock already-unlocked socket"
56 "(StreamSocket*)" << socket
;
59 const IPEndPoint
& endpoint
= socket_it
->second
;
60 DVLOG(3) << "Unlocking (StreamSocket*)" << socket
<< " for "
61 << endpoint
.ToString() << " (" << socket_endpoint_map_
.size()
63 UnlockEndpoint(endpoint
);
64 socket_endpoint_map_
.erase(socket_it
);
67 void WebSocketEndpointLockManager::UnlockEndpoint(const IPEndPoint
& endpoint
) {
68 EndPointWaiterMap::iterator found_it
= endpoint_waiter_map_
.find(endpoint
);
69 CHECK(found_it
!= endpoint_waiter_map_
.end()); // Security critical
70 ConnectJobQueue
* queue
= found_it
->second
;
72 DVLOG(3) << "Unlocking endpoint " << endpoint
.ToString();
74 endpoint_waiter_map_
.erase(found_it
);
76 DVLOG(3) << "Unlocking endpoint " << endpoint
.ToString()
77 << " and activating next waiter";
78 Waiter
* next_job
= queue
->head()->value();
79 next_job
->RemoveFromList();
80 next_job
->GotEndpointLock();
84 bool WebSocketEndpointLockManager::IsEmpty() const {
85 return endpoint_waiter_map_
.empty() && socket_endpoint_map_
.empty();
88 WebSocketEndpointLockManager::WebSocketEndpointLockManager() {}
90 WebSocketEndpointLockManager::~WebSocketEndpointLockManager() {
91 DCHECK(endpoint_waiter_map_
.empty());
92 DCHECK(socket_endpoint_map_
.empty());