OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ | 5 #ifndef NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ |
6 #define NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ | 6 #define NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/containers/linked_list.h" | 10 #include "base/containers/linked_list.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 // Returns OK if lock was acquired immediately, ERR_IO_PENDING if not. If the | 34 // Returns OK if lock was acquired immediately, ERR_IO_PENDING if not. If the |
35 // lock was not acquired, then |waiter->GotEndpointLock()| will be called when | 35 // lock was not acquired, then |waiter->GotEndpointLock()| will be called when |
36 // it is. A Waiter automatically removes itself from the list of waiters when | 36 // it is. A Waiter automatically removes itself from the list of waiters when |
37 // its destructor is called. | 37 // its destructor is called. |
38 int LockEndpoint(const IPEndPoint& endpoint, Waiter* waiter); | 38 int LockEndpoint(const IPEndPoint& endpoint, Waiter* waiter); |
39 | 39 |
40 // Records the IPEndPoint associated with a particular socket. This is | 40 // Records the IPEndPoint associated with a particular socket. This is |
41 // necessary because TCPClientSocket refuses to return the PeerAddress after | 41 // necessary because TCPClientSocket refuses to return the PeerAddress after |
42 // the connection is disconnected. The association will be forgotten when | 42 // the connection is disconnected. The association will be forgotten when |
43 // UnlockSocket() is called. The |socket| pointer must not be deleted between | 43 // UnlockSocket() or UnlockEndpoint() is called. The |socket| pointer must not |
44 // the call to RememberSocket() and the call to UnlockSocket(). | 44 // be deleted between the call to RememberSocket() and the call to |
| 45 // UnlockSocket(). |
45 void RememberSocket(StreamSocket* socket, const IPEndPoint& endpoint); | 46 void RememberSocket(StreamSocket* socket, const IPEndPoint& endpoint); |
46 | 47 |
47 // Releases the lock on an endpoint, and, if appropriate, triggers the next | 48 // Releases the lock on the endpoint that was associated with |socket| by |
48 // socket connection. For a successful WebSocket connection, this method will | 49 // RememberSocket(). If appropriate, triggers the next socket connection. |
49 // be called once when the handshake completes, and again when the connection | 50 // Should be called exactly once for each |socket| that was passed to |
50 // is closed. Calls after the first are safely ignored. | 51 // RememberSocket(). Does nothing if UnlockEndpoint() has been called since |
| 52 // the call to RememberSocket(). |
51 void UnlockSocket(StreamSocket* socket); | 53 void UnlockSocket(StreamSocket* socket); |
52 | 54 |
53 // Releases the lock on |endpoint|. If RememberSocket() has been called for | 55 // Releases the lock on |endpoint|. Does nothing if |endpoint| is not locked. |
54 // this endpoint, then UnlockSocket() must be used instead of this method. | 56 // Removes any socket association that was recorded with RememberSocket(). If |
| 57 // appropriate, calls |waiter->GotEndpointLock()|. |
55 void UnlockEndpoint(const IPEndPoint& endpoint); | 58 void UnlockEndpoint(const IPEndPoint& endpoint); |
56 | 59 |
57 // Checks that |endpoint_waiter_map_| and |socket_endpoint_map_| are | 60 // Checks that |lock_info_map_| and |socket_lock_info_map_| are empty. For |
58 // empty. For tests. | 61 // tests. |
59 bool IsEmpty() const; | 62 bool IsEmpty() const; |
60 | 63 |
61 private: | 64 private: |
62 typedef base::LinkedList<Waiter> ConnectJobQueue; | 65 struct LockInfo { |
63 typedef std::map<IPEndPoint, ConnectJobQueue*> EndPointWaiterMap; | 66 typedef base::LinkedList<Waiter> WaiterQueue; |
64 typedef std::map<StreamSocket*, IPEndPoint> SocketEndPointMap; | 67 |
| 68 LockInfo(); |
| 69 ~LockInfo(); |
| 70 |
| 71 // This object must be copyable to be placed in the map, but it cannot be |
| 72 // copied after |queue| has been assigned to. |
| 73 LockInfo(const LockInfo& rhs); |
| 74 |
| 75 // Not used. |
| 76 LockInfo& operator=(const LockInfo& rhs); |
| 77 |
| 78 // Must be NULL to copy this object into the map. Must be set to non-NULL |
| 79 // after the object is inserted into the map then point to the same list |
| 80 // until this object is deleted. |
| 81 scoped_ptr<WaiterQueue> queue; |
| 82 |
| 83 // This pointer is only used to identify the last instance of StreamSocket |
| 84 // that was passed to RememberSocket() for this endpoint. It should only be |
| 85 // compared with other pointers. It is never dereferenced and not owned. It |
| 86 // is non-NULL if RememberSocket() has been called for this endpoint since |
| 87 // the last call to UnlockSocket() or UnlockEndpoint(). |
| 88 StreamSocket* socket; |
| 89 }; |
| 90 |
| 91 // SocketLockInfoMap requires std::map iterator semantics for LockInfoMap |
| 92 // (ie. that the iterator will remain valid as long as the entry is not |
| 93 // deleted). |
| 94 typedef std::map<IPEndPoint, LockInfo> LockInfoMap; |
| 95 typedef std::map<StreamSocket*, LockInfoMap::iterator> SocketLockInfoMap; |
65 | 96 |
66 WebSocketEndpointLockManager(); | 97 WebSocketEndpointLockManager(); |
67 ~WebSocketEndpointLockManager(); | 98 ~WebSocketEndpointLockManager(); |
68 | 99 |
| 100 void UnlockEndpointByIterator(LockInfoMap::iterator lock_info_it); |
| 101 void EraseSocket(LockInfoMap::iterator lock_info_it); |
| 102 |
69 // If an entry is present in the map for a particular endpoint, then that | 103 // If an entry is present in the map for a particular endpoint, then that |
70 // endpoint is locked. If the list is non-empty, then one or more Waiters are | 104 // endpoint is locked. If LockInfo.queue is non-empty, then one or more |
71 // waiting for the lock. | 105 // Waiters are waiting for the lock. |
72 EndPointWaiterMap endpoint_waiter_map_; | 106 LockInfoMap lock_info_map_; |
73 | 107 |
74 // Store sockets remembered by RememberSocket() and not yet unlocked by | 108 // Store sockets remembered by RememberSocket() and not yet unlocked by |
75 // UnlockSocket(). | 109 // UnlockSocket() or UnlockEndpoint(). Every entry in this map always |
76 SocketEndPointMap socket_endpoint_map_; | 110 // references a live entry in lock_info_map_, and the LockInfo::socket member |
| 111 // is non-NULL if and only if there is an entry in this map for the socket. |
| 112 SocketLockInfoMap socket_lock_info_map_; |
77 | 113 |
78 friend struct DefaultSingletonTraits<WebSocketEndpointLockManager>; | 114 friend struct DefaultSingletonTraits<WebSocketEndpointLockManager>; |
79 | 115 |
80 DISALLOW_COPY_AND_ASSIGN(WebSocketEndpointLockManager); | 116 DISALLOW_COPY_AND_ASSIGN(WebSocketEndpointLockManager); |
81 }; | 117 }; |
82 | 118 |
83 } // namespace net | 119 } // namespace net |
84 | 120 |
85 #endif // NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ | 121 #endif // NET_SOCKET_WEBSOCKET_ENDPOINT_LOCK_MANAGER_H_ |
OLD | NEW |