websocket_endpoint_lock_manager.h revision 116680a4aac90f2aa7413d9095a592090648e557
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <map> 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/containers/linked_list.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/logging.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/macros.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/singleton.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/ip_endpoint.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/net_export.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/socket/websocket_transport_client_socket_pool.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace net { 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass StreamSocket; 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass NET_EXPORT_PRIVATE WebSocketEndpointLockManager { 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch class NET_EXPORT_PRIVATE Waiter : public base::LinkNode<Waiter> { 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the node is in a list, removes it. 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual ~Waiter(); 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void GotEndpointLock() = 0; 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch }; 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static WebSocketEndpointLockManager* GetInstance(); 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Returns OK if lock was acquired immediately, ERR_IO_PENDING if not. If the 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // lock was not acquired, then |waiter->GotEndpointLock()| will be called when 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // it is. A Waiter automatically removes itself from the list of waiters when 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // its destructor is called. 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int LockEndpoint(const IPEndPoint& endpoint, Waiter* waiter); 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Records the IPEndPoint associated with a particular socket. This is 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // necessary because TCPClientSocket refuses to return the PeerAddress after 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the connection is disconnected. The association will be forgotten when 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // UnlockSocket() is called. The |socket| pointer must not be deleted between 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the call to RememberSocket() and the call to UnlockSocket(). 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void RememberSocket(StreamSocket* socket, const IPEndPoint& endpoint); 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Releases the lock on an endpoint, and, if appropriate, triggers the next 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // socket connection. For a successful WebSocket connection, this method will 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // be called once when the handshake completes, and again when the connection 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // is closed. Calls after the first are safely ignored. 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void UnlockSocket(StreamSocket* socket); 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Releases the lock on |endpoint|. If RememberSocket() has been called for 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // this endpoint, then UnlockSocket() must be used instead of this method. 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void UnlockEndpoint(const IPEndPoint& endpoint); 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Checks that |endpoint_waiter_map_| and |socket_endpoint_map_| are 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // empty. For tests. 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool IsEmpty() const; 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef base::LinkedList<Waiter> ConnectJobQueue; 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef std::map<IPEndPoint, ConnectJobQueue*> EndPointWaiterMap; 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef std::map<StreamSocket*, IPEndPoint> SocketEndPointMap; 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch WebSocketEndpointLockManager(); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ~WebSocketEndpointLockManager(); 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If an entry is present in the map for a particular endpoint, then that 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // endpoint is locked. If the list is non-empty, then one or more Waiters are 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // waiting for the lock. 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EndPointWaiterMap endpoint_waiter_map_; 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Store sockets remembered by RememberSocket() and not yet unlocked by 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // UnlockSocket(). 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SocketEndPointMap socket_endpoint_map_; 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch friend struct DefaultSingletonTraits<WebSocketEndpointLockManager>; 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DISALLOW_COPY_AND_ASSIGN(WebSocketEndpointLockManager); 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace net 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ 86