Index: net/socket/websocket_endpoint_lock_manager.h |
diff --git a/net/socket/websocket_endpoint_lock_manager.h b/net/socket/websocket_endpoint_lock_manager.h |
index 7ab25c6744ef898575eaeb9c513a7febaaab27d5..3e3fd4a6486a2e98cd2890d23d9470f7f7211f6c 100644 |
--- a/net/socket/websocket_endpoint_lock_manager.h |
+++ b/net/socket/websocket_endpoint_lock_manager.h |
@@ -40,40 +40,76 @@ class NET_EXPORT_PRIVATE WebSocketEndpointLockManager { |
// Records the IPEndPoint associated with a particular socket. This is |
// necessary because TCPClientSocket refuses to return the PeerAddress after |
// the connection is disconnected. The association will be forgotten when |
- // UnlockSocket() is called. The |socket| pointer must not be deleted between |
- // the call to RememberSocket() and the call to UnlockSocket(). |
+ // UnlockSocket() or UnlockEndpoint() is called. The |socket| pointer must not |
+ // be deleted between the call to RememberSocket() and the call to |
+ // UnlockSocket(). |
void RememberSocket(StreamSocket* socket, const IPEndPoint& endpoint); |
- // Releases the lock on an endpoint, and, if appropriate, triggers the next |
- // socket connection. For a successful WebSocket connection, this method will |
- // be called once when the handshake completes, and again when the connection |
- // is closed. Calls after the first are safely ignored. |
+ // Releases the lock on the endpoint that was associated with |socket| by |
+ // RememberSocket(). If appropriate, triggers the next socket connection. |
+ // Should be called exactly once for each |socket| that was passed to |
+ // RememberSocket(). Does nothing if UnlockEndpoint() has been called since |
+ // the call to RememberSocket(). |
void UnlockSocket(StreamSocket* socket); |
- // Releases the lock on |endpoint|. If RememberSocket() has been called for |
- // this endpoint, then UnlockSocket() must be used instead of this method. |
+ // Releases the lock on |endpoint|. Does nothing if |endpoint| is not locked. |
+ // Removes any socket association that was recorded with RememberSocket(). If |
+ // appropriate, calls |waiter->GotEndpointLock()|. |
void UnlockEndpoint(const IPEndPoint& endpoint); |
- // Checks that |endpoint_waiter_map_| and |socket_endpoint_map_| are |
- // empty. For tests. |
+ // Checks that |lock_info_map_| and |socket_lock_info_map_| are empty. For |
+ // tests. |
bool IsEmpty() const; |
private: |
- typedef base::LinkedList<Waiter> ConnectJobQueue; |
- typedef std::map<IPEndPoint, ConnectJobQueue*> EndPointWaiterMap; |
- typedef std::map<StreamSocket*, IPEndPoint> SocketEndPointMap; |
+ struct LockInfo { |
+ typedef base::LinkedList<Waiter> WaiterQueue; |
+ |
+ LockInfo(); |
+ ~LockInfo(); |
+ |
+ // This object must be copyable to be placed in the map, but it cannot be |
+ // copied after |queue| has been assigned to. |
+ LockInfo(const LockInfo& rhs); |
+ |
+ // Not used. |
+ LockInfo& operator=(const LockInfo& rhs); |
+ |
+ // Must be NULL to copy this object into the map. Must be set to non-NULL |
+ // after the object is inserted into the map then point to the same list |
+ // until this object is deleted. |
+ scoped_ptr<WaiterQueue> queue; |
+ |
+ // This pointer is only used to identify the last instance of StreamSocket |
+ // that was passed to RememberSocket() for this endpoint. It should only be |
+ // compared with other pointers. It is never dereferenced and not owned. It |
+ // is non-NULL if RememberSocket() has been called for this endpoint since |
+ // the last call to UnlockSocket() or UnlockEndpoint(). |
+ StreamSocket* socket; |
+ }; |
+ |
+ // SocketLockInfoMap requires std::map interator semantics for LockInfoMap |
Johnny
2014/08/04 21:23:58
s/interator/iterator/
|
+ // (ie. that the iterator will remain valid as long as the entry is not |
+ // deleted). |
+ typedef std::map<IPEndPoint, LockInfo> LockInfoMap; |
+ typedef std::map<StreamSocket*, LockInfoMap::iterator> SocketLockInfoMap; |
WebSocketEndpointLockManager(); |
~WebSocketEndpointLockManager(); |
+ void UnlockEndpointByIterator(LockInfoMap::iterator lock_info_it); |
+ void EraseSocket(LockInfoMap::iterator lock_info_it); |
+ |
// If an entry is present in the map for a particular endpoint, then that |
- // endpoint is locked. If the list is non-empty, then one or more Waiters are |
- // waiting for the lock. |
- EndPointWaiterMap endpoint_waiter_map_; |
+ // endpoint is locked. If LockInfo.queue is non-empty, then one or more |
+ // Waiters are waiting for the lock. |
+ LockInfoMap lock_info_map_; |
// Store sockets remembered by RememberSocket() and not yet unlocked by |
- // UnlockSocket(). |
- SocketEndPointMap socket_endpoint_map_; |
+ // UnlockSocket() or UnlockEndpoint(). Every entry in this map always |
+ // references a live entry in lock_info_map_, and the LockInfo::socket member |
+ // is non-NULL if and only if there is an entry in this map for the socket. |
+ SocketLockInfoMap socket_lock_info_map_; |
friend struct DefaultSingletonTraits<WebSocketEndpointLockManager>; |