| 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..d5cad508d6ad8622807a8b0f988ba771fae020db 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 iterator semantics for LockInfoMap
|
| + // (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>;
|
|
|
|
|