QUIC - enable persisting of QUICServerInfo (server config) to disk
[chromium-blink-merge.git] / net / socket / websocket_endpoint_lock_manager.cc
blobc8d9a3b0a4602ab2cf93c249df3f2be34c7e5229
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"
7 #include <utility>
9 #include "base/logging.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/net_log.h"
13 namespace net {
15 WebSocketEndpointLockManager::Waiter::~Waiter() {
16 if (next()) {
17 DCHECK(previous());
18 RemoveFromList();
22 WebSocketEndpointLockManager* WebSocketEndpointLockManager::GetInstance() {
23 return Singleton<WebSocketEndpointLockManager>::get();
26 int WebSocketEndpointLockManager::LockEndpoint(const IPEndPoint& endpoint,
27 Waiter* waiter) {
28 EndPointWaiterMap::value_type insert_value(endpoint, NULL);
29 std::pair<EndPointWaiterMap::iterator, bool> rv =
30 endpoint_waiter_map_.insert(insert_value);
31 if (rv.second) {
32 DVLOG(3) << "Locking endpoint " << endpoint.ToString();
33 rv.first->second = new ConnectJobQueue;
34 return OK;
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;
45 DCHECK(inserted);
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;
57 return;
59 const IPEndPoint& endpoint = socket_it->second;
60 DVLOG(3) << "Unlocking (StreamSocket*)" << socket << " for "
61 << endpoint.ToString() << " (" << socket_endpoint_map_.size()
62 << " sockets left)";
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;
71 if (queue->empty()) {
72 DVLOG(3) << "Unlocking endpoint " << endpoint.ToString();
73 delete queue;
74 endpoint_waiter_map_.erase(found_it);
75 } else {
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());
95 } // namespace net