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

Side by Side Diff: net/http/http_pipelined_connection_impl.cc

Issue 8414010: Fix pipelining crash on canceled user callbacks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/http/http_pipelined_connection_impl.h" 5 #include "net/http/http_pipelined_connection_impl.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "net/base/io_buffer.h" 9 #include "net/base/io_buffer.h"
10 #include "net/http/http_pipelined_stream.h" 10 #include "net/http/http_pipelined_stream.h"
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } 216 }
217 if (result < OK) { 217 if (result < OK) {
218 send_next_state_ = SEND_STATE_UNUSABLE; 218 send_next_state_ = SEND_STATE_UNUSABLE;
219 usable_ = false; 219 usable_ = false;
220 } 220 }
221 if (send_user_callback_) { 221 if (send_user_callback_) {
222 MessageLoop::current()->PostTask( 222 MessageLoop::current()->PostTask(
223 FROM_HERE, 223 FROM_HERE,
224 method_factory_.NewRunnableMethod( 224 method_factory_.NewRunnableMethod(
225 &HttpPipelinedConnectionImpl::FireUserCallback, 225 &HttpPipelinedConnectionImpl::FireUserCallback,
226 send_user_callback_, 226 deferred_request.pipeline_id,
227 result)); 227 result));
228 stream_info_map_[deferred_request.pipeline_id].pending_user_callback =
229 send_user_callback_;
228 send_user_callback_ = NULL; 230 send_user_callback_ = NULL;
229 } 231 }
230 if (result < OK) { 232 if (result < OK) {
231 return result; 233 return result;
232 } 234 }
233 if (deferred_request_queue_.empty()) { 235 if (deferred_request_queue_.empty()) {
234 send_next_state_ = SEND_STATE_NONE; 236 send_next_state_ = SEND_STATE_NONE;
235 return OK; 237 return OK;
236 } 238 }
237 send_next_state_ = SEND_STATE_NEXT_REQUEST; 239 send_next_state_ = SEND_STATE_NEXT_REQUEST;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 CHECK_LE(OK, rv); 343 CHECK_LE(OK, rv);
342 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE; 344 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
343 } 345 }
344 346
345 // |result| == ERR_IO_PENDING means this function was *not* called on the same 347 // |result| == ERR_IO_PENDING means this function was *not* called on the same
346 // stack as ReadResponseHeaders(). That means we returned ERR_IO_PENDING to 348 // stack as ReadResponseHeaders(). That means we returned ERR_IO_PENDING to
347 // ReadResponseHeaders() earlier and now need to invoke its callback. 349 // ReadResponseHeaders() earlier and now need to invoke its callback.
348 if (rv != ERR_IO_PENDING && result == ERR_IO_PENDING) { 350 if (rv != ERR_IO_PENDING && result == ERR_IO_PENDING) {
349 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE; 351 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
350 read_user_callback_ = stream_info_map_[pipeline_id].read_headers_callback; 352 read_user_callback_ = stream_info_map_[pipeline_id].read_headers_callback;
353 stream_info_map_[pipeline_id].pending_user_callback = read_user_callback_;
351 MessageLoop::current()->PostTask( 354 MessageLoop::current()->PostTask(
352 FROM_HERE, 355 FROM_HERE,
353 method_factory_.NewRunnableMethod( 356 method_factory_.NewRunnableMethod(
354 &HttpPipelinedConnectionImpl::FireUserCallback, 357 &HttpPipelinedConnectionImpl::FireUserCallback,
355 read_user_callback_, 358 pipeline_id,
356 rv)); 359 rv));
357 } 360 }
358 return rv; 361 return rv;
359 } 362 }
360 363
361 int HttpPipelinedConnectionImpl::DoReadHeadersComplete(int result) { 364 int HttpPipelinedConnectionImpl::DoReadHeadersComplete(int result) {
362 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE; 365 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
363 if (read_user_callback_) { 366 if (read_user_callback_) {
367 int pipeline_id = request_order_.front();
364 MessageLoop::current()->PostTask( 368 MessageLoop::current()->PostTask(
365 FROM_HERE, 369 FROM_HERE,
366 method_factory_.NewRunnableMethod( 370 method_factory_.NewRunnableMethod(
367 &HttpPipelinedConnectionImpl::FireUserCallback, 371 &HttpPipelinedConnectionImpl::FireUserCallback,
368 read_user_callback_, 372 pipeline_id,
369 result)); 373 result));
374 stream_info_map_[pipeline_id].pending_user_callback = read_user_callback_;
370 read_user_callback_ = NULL; 375 read_user_callback_ = NULL;
371 } 376 }
372 return result; 377 return result;
373 } 378 }
374 379
375 int HttpPipelinedConnectionImpl::DoReadWaitingForClose(int result) { 380 int HttpPipelinedConnectionImpl::DoReadWaitingForClose(int result) {
376 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE; 381 read_next_state_ = READ_STATE_WAITING_FOR_CLOSE;
377 return result; 382 return result;
378 } 383 }
379 384
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 416
412 int HttpPipelinedConnectionImpl::DoEvictPendingReadHeaders(int result) { 417 int HttpPipelinedConnectionImpl::DoEvictPendingReadHeaders(int result) {
413 while (!request_order_.empty()) { 418 while (!request_order_.empty()) {
414 int evicted_id = request_order_.front(); 419 int evicted_id = request_order_.front();
415 request_order_.pop(); 420 request_order_.pop();
416 if (!ContainsKey(stream_info_map_, evicted_id) || 421 if (!ContainsKey(stream_info_map_, evicted_id) ||
417 (stream_info_map_[evicted_id].read_headers_callback == NULL)) { 422 (stream_info_map_[evicted_id].read_headers_callback == NULL)) {
418 continue; 423 continue;
419 } 424 }
420 if (stream_info_map_[evicted_id].state != STREAM_CLOSED) { 425 if (stream_info_map_[evicted_id].state != STREAM_CLOSED) {
426 stream_info_map_[evicted_id].pending_user_callback =
427 stream_info_map_[evicted_id].read_headers_callback;
421 MessageLoop::current()->PostTask( 428 MessageLoop::current()->PostTask(
422 FROM_HERE, 429 FROM_HERE,
423 method_factory_.NewRunnableMethod( 430 method_factory_.NewRunnableMethod(
424 &HttpPipelinedConnectionImpl::FireUserCallback, 431 &HttpPipelinedConnectionImpl::FireUserCallback,
425 stream_info_map_[evicted_id].read_headers_callback, 432 evicted_id,
426 ERR_PIPELINE_EVICTION)); 433 ERR_PIPELINE_EVICTION));
427 } 434 }
428 stream_info_map_[evicted_id].read_headers_callback = NULL; 435 stream_info_map_[evicted_id].read_headers_callback = NULL;
429 } 436 }
430 read_next_state_ = READ_STATE_NONE; 437 read_next_state_ = READ_STATE_NONE;
431 return result; 438 return result;
432 } 439 }
433 440
434 void HttpPipelinedConnectionImpl::Close(int pipeline_id, 441 void HttpPipelinedConnectionImpl::Close(int pipeline_id,
435 bool not_reusable) { 442 bool not_reusable) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 560
554 void HttpPipelinedConnectionImpl::GetSSLCertRequestInfo( 561 void HttpPipelinedConnectionImpl::GetSSLCertRequestInfo(
555 int pipeline_id, 562 int pipeline_id,
556 SSLCertRequestInfo* cert_request_info) { 563 SSLCertRequestInfo* cert_request_info) {
557 CHECK(ContainsKey(stream_info_map_, pipeline_id)); 564 CHECK(ContainsKey(stream_info_map_, pipeline_id));
558 CHECK(stream_info_map_[pipeline_id].parser.get()); 565 CHECK(stream_info_map_[pipeline_id].parser.get());
559 return stream_info_map_[pipeline_id].parser->GetSSLCertRequestInfo( 566 return stream_info_map_[pipeline_id].parser->GetSSLCertRequestInfo(
560 cert_request_info); 567 cert_request_info);
561 } 568 }
562 569
563 void HttpPipelinedConnectionImpl::FireUserCallback( 570 void HttpPipelinedConnectionImpl::FireUserCallback(int pipeline_id,
564 OldCompletionCallback* callback, 571 int result) {
565 int result) { 572 if (ContainsKey(stream_info_map_, pipeline_id)) {
566 CHECK(callback); 573 CHECK(stream_info_map_[pipeline_id].pending_user_callback);
567 callback->Run(result); 574 stream_info_map_[pipeline_id].pending_user_callback->Run(result);
575 }
568 } 576 }
569 577
570 int HttpPipelinedConnectionImpl::depth() const { 578 int HttpPipelinedConnectionImpl::depth() const {
571 return stream_info_map_.size(); 579 return stream_info_map_.size();
572 } 580 }
573 581
574 bool HttpPipelinedConnectionImpl::usable() const { 582 bool HttpPipelinedConnectionImpl::usable() const {
575 return usable_; 583 return usable_;
576 } 584 }
577 585
(...skipping 25 matching lines...) Expand all
603 611
604 HttpPipelinedConnectionImpl::StreamInfo::StreamInfo() 612 HttpPipelinedConnectionImpl::StreamInfo::StreamInfo()
605 : read_headers_callback(NULL), 613 : read_headers_callback(NULL),
606 state(STREAM_CREATED) { 614 state(STREAM_CREATED) {
607 } 615 }
608 616
609 HttpPipelinedConnectionImpl::StreamInfo::~StreamInfo() { 617 HttpPipelinedConnectionImpl::StreamInfo::~StreamInfo() {
610 } 618 }
611 619
612 } // namespace net 620 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698