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