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

Side by Side Diff: webkit/tools/test_shell/simple_resource_loader_bridge.cc

Issue 10012010: Force deletion of test_shell's RequestProxy on the IO thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // This file contains an implementation of the ResourceLoaderBridge class. 5 // This file contains an implementation of the ResourceLoaderBridge class.
6 // The class is implemented using net::URLRequest, meaning it is a "simple" 6 // The class is implemented using net::URLRequest, meaning it is a "simple"
7 // version that directly issues requests. The more complicated one used in the 7 // version that directly issues requests. The more complicated one used in the
8 // browser uses IPC. 8 // browser uses IPC.
9 // 9 //
10 // Because net::URLRequest only provides an asynchronous resource loading API, 10 // Because net::URLRequest only provides an asynchronous resource loading API,
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 scoped_refptr<net::UploadData> upload; 266 scoped_refptr<net::UploadData> upload;
267 }; 267 };
268 268
269 // The interval for calls to RequestProxy::MaybeUpdateUploadProgress 269 // The interval for calls to RequestProxy::MaybeUpdateUploadProgress
270 static const int kUpdateUploadProgressIntervalMsec = 100; 270 static const int kUpdateUploadProgressIntervalMsec = 100;
271 271
272 // The RequestProxy does most of its work on the IO thread. The Start and 272 // The RequestProxy does most of its work on the IO thread. The Start and
273 // Cancel methods are proxied over to the IO thread, where an net::URLRequest 273 // Cancel methods are proxied over to the IO thread, where an net::URLRequest
274 // object is instantiated. 274 // object is instantiated.
275 class RequestProxy : public net::URLRequest::Delegate, 275 class RequestProxy : public net::URLRequest::Delegate,
276 public base::RefCountedThreadSafe<RequestProxy> { 276 public base::RefCountedThreadSafe<RequestProxy> {
darin (slow to review) 2012/04/05 20:45:21 wouldn't it be simpler to just use a Traits class
Ami GONE FROM CHROMIUM 2012/04/05 22:14:31 Hell yes. That'd qualify as "a better way to expr
277 public: 277 public:
278 // Takes ownership of the params. 278 // Takes ownership of the params.
279 RequestProxy() 279 RequestProxy()
280 : download_to_file_(false), 280 : download_to_file_(false),
281 file_stream_(NULL), 281 file_stream_(NULL),
282 buf_(new net::IOBuffer(kDataSize)), 282 buf_(new net::IOBuffer(kDataSize)),
283 last_upload_position_(0) { 283 last_upload_position_(0) {
284 } 284 }
285 285
286 void DropPeer() { 286 void DropPeer() {
287 peer_ = NULL; 287 peer_ = NULL;
288 } 288 }
289 289
290 void Start(ResourceLoaderBridge::Peer* peer, RequestParams* params) { 290 void Start(ResourceLoaderBridge::Peer* peer, RequestParams* params) {
291 peer_ = peer; 291 peer_ = peer;
292 owner_loop_ = MessageLoop::current(); 292 owner_loop_ = base::MessageLoopProxy::current();
293 293
294 ConvertRequestParamsForFileOverHTTPIfNeeded(params); 294 ConvertRequestParamsForFileOverHTTPIfNeeded(params);
295 // proxy over to the io thread 295 // proxy over to the io thread
296 g_io_thread->message_loop()->PostTask( 296 g_io_thread->message_loop()->PostTask(
297 FROM_HERE, 297 FROM_HERE,
298 base::Bind(&RequestProxy::AsyncStart, this, params)); 298 base::Bind(&RequestProxy::AsyncStart, this, params));
299 } 299 }
300 300
301 void Cancel() { 301 void Cancel() {
302 // proxy over to the io thread 302 // proxy over to the io thread
303 g_io_thread->message_loop()->PostTask( 303 g_io_thread->message_loop()->PostTask(
304 FROM_HERE, 304 FROM_HERE,
305 base::Bind(&RequestProxy::AsyncCancel, this)); 305 base::Bind(&RequestProxy::AsyncCancel, this));
306 } 306 }
307 307
308 protected: 308 protected:
309 friend class base::RefCountedThreadSafe<RequestProxy>; 309 friend class base::RefCountedThreadSafe<RequestProxy>;
310 310
311 virtual ~RequestProxy() { 311 virtual ~RequestProxy() {
312 // If we have a request, then we'd better be on the io thread! 312 // Ensure we are deleted on the IO thread because base::Timer requires that.
313 DCHECK(!request_.get() || 313 DCHECK(MessageLoop::current() == g_io_thread->message_loop());
314 MessageLoop::current() == g_io_thread->message_loop());
315 } 314 }
316 315
317 // -------------------------------------------------------------------------- 316 // --------------------------------------------------------------------------
318 // The following methods are called on the owner's thread in response to 317 // The following methods are called on the owner's thread in response to
319 // various net::URLRequest callbacks. The event hooks, defined below, trigger 318 // various net::URLRequest callbacks. The event hooks, defined below, trigger
320 // these methods asynchronously. 319 // these methods asynchronously.
321 320
322 void NotifyReceivedRedirect(const GURL& new_url, 321 void NotifyReceivedRedirect(const GURL& new_url,
323 const ResourceResponseInfo& info) { 322 const ResourceResponseInfo& info) {
324 bool has_new_first_party_for_cookies = false; 323 bool has_new_first_party_for_cookies = false;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 } // else wait for OnReadCompleted 471 } // else wait for OnReadCompleted
473 } else { 472 } else {
474 Done(); 473 Done();
475 } 474 }
476 } 475 }
477 476
478 // -------------------------------------------------------------------------- 477 // --------------------------------------------------------------------------
479 // The following methods are event hooks (corresponding to net::URLRequest 478 // The following methods are event hooks (corresponding to net::URLRequest
480 // callbacks) that run on the IO thread. They are designed to be overridden 479 // callbacks) that run on the IO thread. They are designed to be overridden
481 // by the SyncRequestProxy subclass. 480 // by the SyncRequestProxy subclass.
481 //
482 // Note that since |this| must be ultimately destroyed on the IO thread, each
483 // of these uses a do-nothing reply closure to extend |this|'s lifetime long
484 // enough to avoid being deleted on the owner thread.
482 485
483 virtual void OnReceivedRedirect( 486 virtual void OnReceivedRedirect(
484 const GURL& new_url, 487 const GURL& new_url,
485 const ResourceResponseInfo& info, 488 const ResourceResponseInfo& info,
486 bool* defer_redirect) { 489 bool* defer_redirect) {
487 *defer_redirect = true; // See AsyncFollowDeferredRedirect 490 *defer_redirect = true; // See AsyncFollowDeferredRedirect
488 owner_loop_->PostTask( 491 owner_loop_->PostTaskAndReply(
489 FROM_HERE, 492 FROM_HERE,
490 base::Bind(&RequestProxy::NotifyReceivedRedirect, this, new_url, info)); 493 base::Bind(&RequestProxy::NotifyReceivedRedirect, this, new_url, info),
494 base::Bind(&RequestProxy::DoNothing, this));
491 } 495 }
492 496
493 virtual void OnReceivedResponse( 497 virtual void OnReceivedResponse(
494 const ResourceResponseInfo& info) { 498 const ResourceResponseInfo& info) {
495 owner_loop_->PostTask( 499 owner_loop_->PostTaskAndReply(
496 FROM_HERE, 500 FROM_HERE,
497 base::Bind(&RequestProxy::NotifyReceivedResponse, this, info)); 501 base::Bind(&RequestProxy::NotifyReceivedResponse, this, info),
502 base::Bind(&RequestProxy::DoNothing, this));
498 } 503 }
499 504
500 virtual void OnReceivedData(int bytes_read) { 505 virtual void OnReceivedData(int bytes_read) {
501 if (download_to_file_) { 506 if (download_to_file_) {
502 file_stream_.WriteSync(buf_->data(), bytes_read); 507 file_stream_.WriteSync(buf_->data(), bytes_read);
503 owner_loop_->PostTask( 508 owner_loop_->PostTaskAndReply(
504 FROM_HERE, 509 FROM_HERE,
505 base::Bind(&RequestProxy::NotifyDownloadedData, this, bytes_read)); 510 base::Bind(&RequestProxy::NotifyDownloadedData, this, bytes_read),
511 base::Bind(&RequestProxy::DoNothing, this));
506 return; 512 return;
507 } 513 }
508 514
509 owner_loop_->PostTask( 515 owner_loop_->PostTaskAndReply(
510 FROM_HERE, 516 FROM_HERE,
511 base::Bind(&RequestProxy::NotifyReceivedData, this, bytes_read)); 517 base::Bind(&RequestProxy::NotifyReceivedData, this, bytes_read),
518 base::Bind(&RequestProxy::DoNothing, this));
512 } 519 }
513 520
514 virtual void OnCompletedRequest(const net::URLRequestStatus& status, 521 virtual void OnCompletedRequest(const net::URLRequestStatus& status,
515 const std::string& security_info, 522 const std::string& security_info,
516 const base::TimeTicks& complete_time) { 523 const base::TimeTicks& complete_time) {
517 if (download_to_file_) 524 if (download_to_file_)
518 file_stream_.CloseSync(); 525 file_stream_.CloseSync();
519 owner_loop_->PostTask( 526 owner_loop_->PostTaskAndReply(
520 FROM_HERE, 527 FROM_HERE,
521 base::Bind(&RequestProxy::NotifyCompletedRequest, this, status, 528 base::Bind(&RequestProxy::NotifyCompletedRequest, this, status,
522 security_info, complete_time)); 529 security_info, complete_time),
530 base::Bind(&RequestProxy::DoNothing, this));
523 } 531 }
524 532
525 // -------------------------------------------------------------------------- 533 // --------------------------------------------------------------------------
526 // net::URLRequest::Delegate implementation: 534 // net::URLRequest::Delegate implementation:
527 535
528 virtual void OnReceivedRedirect(net::URLRequest* request, 536 virtual void OnReceivedRedirect(net::URLRequest* request,
529 const GURL& new_url, 537 const GURL& new_url,
530 bool* defer_redirect) OVERRIDE { 538 bool* defer_redirect) OVERRIDE {
531 DCHECK(request->status().is_success()); 539 DCHECK(request->status().is_success());
532 ResourceResponseInfo info; 540 ResourceResponseInfo info;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 uint64 amt_since_last = position - last_upload_position_; 618 uint64 amt_since_last = position - last_upload_position_;
611 base::TimeDelta time_since_last = base::TimeTicks::Now() - 619 base::TimeDelta time_since_last = base::TimeTicks::Now() -
612 last_upload_ticks_; 620 last_upload_ticks_;
613 621
614 bool is_finished = (size == position); 622 bool is_finished = (size == position);
615 bool enough_new_progress = (amt_since_last > (size / 623 bool enough_new_progress = (amt_since_last > (size /
616 kHalfPercentIncrements)); 624 kHalfPercentIncrements));
617 bool too_much_time_passed = time_since_last > kOneSecond; 625 bool too_much_time_passed = time_since_last > kOneSecond;
618 626
619 if (is_finished || enough_new_progress || too_much_time_passed) { 627 if (is_finished || enough_new_progress || too_much_time_passed) {
620 owner_loop_->PostTask( 628 owner_loop_->PostTaskAndReply(
621 FROM_HERE, 629 FROM_HERE,
622 base::Bind(&RequestProxy::NotifyUploadProgress, this, position, 630 base::Bind(&RequestProxy::NotifyUploadProgress, this, position, size),
623 size)); 631 base::Bind(&RequestProxy::DoNothing, this));
624 last_upload_ticks_ = base::TimeTicks::Now(); 632 last_upload_ticks_ = base::TimeTicks::Now();
625 last_upload_position_ = position; 633 last_upload_position_ = position;
626 } 634 }
627 } 635 }
628 636
629 void PopulateResponseInfo(net::URLRequest* request, 637 void PopulateResponseInfo(net::URLRequest* request,
630 ResourceResponseInfo* info) const { 638 ResourceResponseInfo* info) const {
631 info->request_time = request->request_time(); 639 info->request_time = request->request_time();
632 info->response_time = request->response_time(); 640 info->response_time = request->response_time();
633 info->headers = request->response_headers(); 641 info->headers = request->response_headers();
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 bool download_to_file_; 732 bool download_to_file_;
725 net::FileStream file_stream_; 733 net::FileStream file_stream_;
726 scoped_refptr<ShareableFileReference> downloaded_file_; 734 scoped_refptr<ShareableFileReference> downloaded_file_;
727 735
728 // Size of our async IO data buffers 736 // Size of our async IO data buffers
729 static const int kDataSize = 16*1024; 737 static const int kDataSize = 16*1024;
730 738
731 // read buffer for async IO 739 // read buffer for async IO
732 scoped_refptr<net::IOBuffer> buf_; 740 scoped_refptr<net::IOBuffer> buf_;
733 741
734 MessageLoop* owner_loop_; 742 scoped_refptr<base::MessageLoopProxy> owner_loop_;
735 743
736 // This is our peer in WebKit (implemented as ResourceHandleInternal). We do 744 // This is our peer in WebKit (implemented as ResourceHandleInternal). We do
737 // not manage its lifetime, and we may only access it from the owner's 745 // not manage its lifetime, and we may only access it from the owner's
738 // message loop (owner_loop_). 746 // message loop (owner_loop_).
739 ResourceLoaderBridge::Peer* peer_; 747 ResourceLoaderBridge::Peer* peer_;
740 748
741 // Timer used to pull upload progress info. 749 // Timer used to pull upload progress info.
742 base::RepeatingTimer<RequestProxy> upload_progress_timer_; 750 base::RepeatingTimer<RequestProxy> upload_progress_timer_;
743 751
744 // Info used to determine whether or not to send an upload progress update. 752 // Info used to determine whether or not to send an upload progress update.
745 uint64 last_upload_position_; 753 uint64 last_upload_position_;
746 base::TimeTicks last_upload_ticks_; 754 base::TimeTicks last_upload_ticks_;
747 755
748 // Save the real FILE URL prefix for the FILE URL which converts to HTTP URL. 756 // Save the real FILE URL prefix for the FILE URL which converts to HTTP URL.
749 std::string file_url_prefix_; 757 std::string file_url_prefix_;
750 // Save a failed file request status to pass it to webkit. 758 // Save a failed file request status to pass it to webkit.
751 scoped_ptr<net::URLRequestStatus> failed_file_request_status_; 759 scoped_ptr<net::URLRequestStatus> failed_file_request_status_;
760
761 private:
762 // Helper used to extend the lifetime of |this| to ensure deletion on the IO
763 // thread.
764 void DoNothing() {}
752 }; 765 };
753 766
754 //----------------------------------------------------------------------------- 767 //-----------------------------------------------------------------------------
755 768
756 class SyncRequestProxy : public RequestProxy { 769 class SyncRequestProxy : public RequestProxy {
757 public: 770 public:
758 explicit SyncRequestProxy(ResourceLoaderBridge::SyncLoadResponse* result) 771 explicit SyncRequestProxy(ResourceLoaderBridge::SyncLoadResponse* result)
759 : result_(result), event_(true, false) { 772 : result_(result), event_(true, false) {
760 } 773 }
761 774
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 (http_prefix.SchemeIs("http") || http_prefix.SchemeIs("https"))); 1113 (http_prefix.SchemeIs("http") || http_prefix.SchemeIs("https")));
1101 g_file_over_http_params = new FileOverHTTPParams(file_path_template, 1114 g_file_over_http_params = new FileOverHTTPParams(file_path_template,
1102 http_prefix); 1115 http_prefix);
1103 } 1116 }
1104 1117
1105 // static 1118 // static
1106 webkit_glue::ResourceLoaderBridge* SimpleResourceLoaderBridge::Create( 1119 webkit_glue::ResourceLoaderBridge* SimpleResourceLoaderBridge::Create(
1107 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) { 1120 const webkit_glue::ResourceLoaderBridge::RequestInfo& request_info) {
1108 return new ResourceLoaderBridgeImpl(request_info); 1121 return new ResourceLoaderBridgeImpl(request_info);
1109 } 1122 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698