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

Side by Side Diff: net/spdy/spdy_session.cc

Issue 5174005: Fix SPDY crash on race when canceling a stream that just got created. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 10 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #include "net/spdy/spdy_session.h" 5 #include "net/spdy/spdy_session.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/linked_ptr.h" 8 #include "base/linked_ptr.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 266
267 if (connection_->is_initialized()) { 267 if (connection_->is_initialized()) {
268 // With Spdy we can't recycle sockets. 268 // With Spdy we can't recycle sockets.
269 connection_->socket()->Disconnect(); 269 connection_->socket()->Disconnect();
270 } 270 }
271 271
272 // Streams should all be gone now. 272 // Streams should all be gone now.
273 DCHECK_EQ(0u, num_active_streams()); 273 DCHECK_EQ(0u, num_active_streams());
274 DCHECK_EQ(0u, num_unclaimed_pushed_streams()); 274 DCHECK_EQ(0u, num_unclaimed_pushed_streams());
275 275
276 DCHECK(pending_callback_map_.empty());
277
276 RecordHistograms(); 278 RecordHistograms();
277 279
278 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION, NULL); 280 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION, NULL);
279 } 281 }
280 282
281 net::Error SpdySession::InitializeWithSocket( 283 net::Error SpdySession::InitializeWithSocket(
282 ClientSocketHandle* connection, 284 ClientSocketHandle* connection,
283 bool is_secure, 285 bool is_secure,
284 int certificate_error_code) { 286 int certificate_error_code) {
285 static base::StatsCounter spdy_sessions("spdy.sessions"); 287 static base::StatsCounter spdy_sessions("spdy.sessions");
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 bool no_pending_create_streams = true; 355 bool no_pending_create_streams = true;
354 for (int i = 0;i < NUM_PRIORITIES;++i) { 356 for (int i = 0;i < NUM_PRIORITIES;++i) {
355 if (!create_stream_queues_[i].empty()) { 357 if (!create_stream_queues_[i].empty()) {
356 PendingCreateStream pending_create = create_stream_queues_[i].front(); 358 PendingCreateStream pending_create = create_stream_queues_[i].front();
357 create_stream_queues_[i].pop(); 359 create_stream_queues_[i].pop();
358 no_pending_create_streams = false; 360 no_pending_create_streams = false;
359 int error = CreateStreamImpl(*pending_create.url, 361 int error = CreateStreamImpl(*pending_create.url,
360 pending_create.priority, 362 pending_create.priority,
361 pending_create.spdy_stream, 363 pending_create.spdy_stream,
362 *pending_create.stream_net_log); 364 *pending_create.stream_net_log);
365 scoped_refptr<SpdyStream>* stream = pending_create.spdy_stream;
366 DCHECK(!ContainsKey(pending_callback_map_, stream));
367 pending_callback_map_[stream] =
368 CallbackResultPair(pending_create.callback, error);
363 MessageLoop::current()->PostTask( 369 MessageLoop::current()->PostTask(
364 FROM_HERE, 370 FROM_HERE,
365 method_factory_.NewRunnableMethod( 371 method_factory_.NewRunnableMethod(
366 &SpdySession::InvokeUserStreamCreationCallback, 372 &SpdySession::InvokeUserStreamCreationCallback, stream));
367 pending_create.callback, error));
368 break; 373 break;
369 } 374 }
370 } 375 }
371 if (no_pending_create_streams) 376 if (no_pending_create_streams)
372 return; // there were no streams in any queue 377 return; // there were no streams in any queue
373 } 378 }
374 } 379 }
375 380
376 void SpdySession::CancelPendingCreateStreams( 381 void SpdySession::CancelPendingCreateStreams(
377 const scoped_refptr<SpdyStream>* spdy_stream) { 382 const scoped_refptr<SpdyStream>* spdy_stream) {
383 PendingCallbackMap::iterator it = pending_callback_map_.find(spdy_stream);
384 if (it != pending_callback_map_.end()) {
385 pending_callback_map_.erase(it);
386 return;
387 }
388
378 for (int i = 0;i < NUM_PRIORITIES;++i) { 389 for (int i = 0;i < NUM_PRIORITIES;++i) {
379 PendingCreateStreamQueue tmp; 390 PendingCreateStreamQueue tmp;
380 // Make a copy removing this trans 391 // Make a copy removing this trans
381 while (!create_stream_queues_[i].empty()) { 392 while (!create_stream_queues_[i].empty()) {
382 PendingCreateStream pending_create = create_stream_queues_[i].front(); 393 PendingCreateStream pending_create = create_stream_queues_[i].front();
383 create_stream_queues_[i].pop(); 394 create_stream_queues_[i].pop();
384 if (pending_create.spdy_stream != spdy_stream) 395 if (pending_create.spdy_stream != spdy_stream)
385 tmp.push(pending_create); 396 tmp.push(pending_create);
386 } 397 }
387 // Now copy it back 398 // Now copy it back
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", 1346 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate",
1336 setting.second, 1347 setting.second,
1337 1, 100, 50); 1348 1, 100, 50);
1338 break; 1349 break;
1339 } 1350 }
1340 } 1351 }
1341 } 1352 }
1342 } 1353 }
1343 1354
1344 void SpdySession::InvokeUserStreamCreationCallback( 1355 void SpdySession::InvokeUserStreamCreationCallback(
1345 CompletionCallback* callback, int rv) { 1356 scoped_refptr<SpdyStream>* stream) {
1346 callback->Run(rv); 1357 PendingCallbackMap::iterator it = pending_callback_map_.find(stream);
1358
1359 // Exit if the request has already been cancelled.
1360 if (it == pending_callback_map_.end())
1361 return;
1362
1363 CompletionCallback* callback = it->second.callback;
1364 int result = it->second.result;
1365 pending_callback_map_.erase(it);
1366 callback->Run(result);
1347 } 1367 }
1348 1368
1349 } // namespace net 1369 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698