Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Unified Diff: net/socket/websocket_endpoint_lock_manager.cc

Issue 436493002: Handle multiple simultanous wss: connections. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Two tiny comment fixes. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/socket/websocket_endpoint_lock_manager.cc
diff --git a/net/socket/websocket_endpoint_lock_manager.cc b/net/socket/websocket_endpoint_lock_manager.cc
index c8d9a3b0a4602ab2cf93c249df3f2be34c7e5229..4afa1130c566ef7f1f86720a930bbf308f35f5b1 100644
--- a/net/socket/websocket_endpoint_lock_manager.cc
+++ b/net/socket/websocket_endpoint_lock_manager.cc
@@ -25,71 +25,107 @@ WebSocketEndpointLockManager* WebSocketEndpointLockManager::GetInstance() {
int WebSocketEndpointLockManager::LockEndpoint(const IPEndPoint& endpoint,
Waiter* waiter) {
- EndPointWaiterMap::value_type insert_value(endpoint, NULL);
- std::pair<EndPointWaiterMap::iterator, bool> rv =
- endpoint_waiter_map_.insert(insert_value);
+ LockInfoMap::value_type insert_value(endpoint, LockInfo());
+ std::pair<LockInfoMap::iterator, bool> rv =
+ lock_info_map_.insert(insert_value);
if (rv.second) {
DVLOG(3) << "Locking endpoint " << endpoint.ToString();
- rv.first->second = new ConnectJobQueue;
+ rv.first->second.queue.reset(new LockInfo::WaiterQueue);
return OK;
}
DVLOG(3) << "Waiting for endpoint " << endpoint.ToString();
- rv.first->second->Append(waiter);
+ rv.first->second.queue->Append(waiter);
return ERR_IO_PENDING;
}
void WebSocketEndpointLockManager::RememberSocket(StreamSocket* socket,
const IPEndPoint& endpoint) {
- bool inserted = socket_endpoint_map_.insert(SocketEndPointMap::value_type(
- socket, endpoint)).second;
+ LockInfoMap::iterator lock_info_it = lock_info_map_.find(endpoint);
+ CHECK(lock_info_it != lock_info_map_.end());
+ bool inserted =
+ socket_lock_info_map_.insert(SocketLockInfoMap::value_type(
+ socket, lock_info_it)).second;
DCHECK(inserted);
- DCHECK(endpoint_waiter_map_.find(endpoint) != endpoint_waiter_map_.end());
+ DCHECK(!lock_info_it->second.socket);
+ lock_info_it->second.socket = socket;
DVLOG(3) << "Remembered (StreamSocket*)" << socket << " for "
- << endpoint.ToString() << " (" << socket_endpoint_map_.size()
- << " sockets remembered)";
+ << endpoint.ToString() << " (" << socket_lock_info_map_.size()
+ << " socket(s) remembered)";
}
void WebSocketEndpointLockManager::UnlockSocket(StreamSocket* socket) {
- SocketEndPointMap::iterator socket_it = socket_endpoint_map_.find(socket);
- if (socket_it == socket_endpoint_map_.end()) {
- DVLOG(3) << "Ignoring request to unlock already-unlocked socket"
- "(StreamSocket*)" << socket;
+ SocketLockInfoMap::iterator socket_it = socket_lock_info_map_.find(socket);
+ if (socket_it == socket_lock_info_map_.end())
return;
- }
- const IPEndPoint& endpoint = socket_it->second;
+
+ LockInfoMap::iterator lock_info_it = socket_it->second;
+
DVLOG(3) << "Unlocking (StreamSocket*)" << socket << " for "
- << endpoint.ToString() << " (" << socket_endpoint_map_.size()
- << " sockets left)";
- UnlockEndpoint(endpoint);
- socket_endpoint_map_.erase(socket_it);
+ << lock_info_it->first.ToString() << " ("
+ << socket_lock_info_map_.size() << " socket(s) left)";
+ socket_lock_info_map_.erase(socket_it);
+ DCHECK(socket == lock_info_it->second.socket);
+ lock_info_it->second.socket = NULL;
+ UnlockEndpointByIterator(lock_info_it);
}
void WebSocketEndpointLockManager::UnlockEndpoint(const IPEndPoint& endpoint) {
- EndPointWaiterMap::iterator found_it = endpoint_waiter_map_.find(endpoint);
- CHECK(found_it != endpoint_waiter_map_.end()); // Security critical
- ConnectJobQueue* queue = found_it->second;
- if (queue->empty()) {
- DVLOG(3) << "Unlocking endpoint " << endpoint.ToString();
- delete queue;
- endpoint_waiter_map_.erase(found_it);
- } else {
- DVLOG(3) << "Unlocking endpoint " << endpoint.ToString()
- << " and activating next waiter";
- Waiter* next_job = queue->head()->value();
- next_job->RemoveFromList();
- next_job->GotEndpointLock();
- }
+ LockInfoMap::iterator lock_info_it = lock_info_map_.find(endpoint);
+ if (lock_info_it == lock_info_map_.end())
+ return;
+
+ UnlockEndpointByIterator(lock_info_it);
}
bool WebSocketEndpointLockManager::IsEmpty() const {
- return endpoint_waiter_map_.empty() && socket_endpoint_map_.empty();
+ return lock_info_map_.empty() && socket_lock_info_map_.empty();
+}
+
+WebSocketEndpointLockManager::LockInfo::LockInfo() : socket(NULL) {}
+WebSocketEndpointLockManager::LockInfo::~LockInfo() {
+ DCHECK(!socket);
+}
+
+WebSocketEndpointLockManager::LockInfo::LockInfo(const LockInfo& rhs)
+ : socket(rhs.socket) {
+ DCHECK(!rhs.queue);
}
WebSocketEndpointLockManager::WebSocketEndpointLockManager() {}
WebSocketEndpointLockManager::~WebSocketEndpointLockManager() {
- DCHECK(endpoint_waiter_map_.empty());
- DCHECK(socket_endpoint_map_.empty());
+ DCHECK(lock_info_map_.empty());
+ DCHECK(socket_lock_info_map_.empty());
+}
+
+void WebSocketEndpointLockManager::UnlockEndpointByIterator(
+ LockInfoMap::iterator lock_info_it) {
+ if (lock_info_it->second.socket)
+ EraseSocket(lock_info_it);
+ scoped_ptr<LockInfo::WaiterQueue>& queue = lock_info_it->second.queue;
tyoshino (SeeGerritForStatus) 2014/08/01 11:31:44 how about just using a pointer?
Adam Rice 2014/08/01 14:09:39 Done.
+ if (queue->empty()) {
+ DVLOG(3) << "Unlocking endpoint " << lock_info_it->first.ToString();
+ queue.reset();
tyoshino (SeeGerritForStatus) 2014/08/01 11:31:44 then, you need to call it on to lock_info_it->seco
Adam Rice 2014/08/01 14:09:39 I just removed the reset() completely, since the s
+ lock_info_map_.erase(lock_info_it);
+ return;
+ }
+
+ DVLOG(3) << "Unlocking endpoint " << lock_info_it->first.ToString()
+ << " and activating next waiter";
+ Waiter* next_job = queue->head()->value();
+ next_job->RemoveFromList();
+ // This must be last to minimise the excitement caused by re-entrancy.
+ next_job->GotEndpointLock();
+}
+
+void WebSocketEndpointLockManager::EraseSocket(
+ LockInfoMap::iterator lock_info_it) {
+ DVLOG(3) << "Removing (StreamSocket*)" << lock_info_it->second.socket
+ << " for " << lock_info_it->first.ToString() << " ("
+ << socket_lock_info_map_.size() << " socket(s) left)";
+ size_t erased = socket_lock_info_map_.erase(lock_info_it->second.socket);
+ DCHECK_EQ(1U, erased);
+ lock_info_it->second.socket = NULL;
}
} // namespace net
« no previous file with comments | « net/socket/websocket_endpoint_lock_manager.h ('k') | net/socket/websocket_endpoint_lock_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698