diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-24 01:54:05 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-24 01:54:05 +0000 |
commit | 1f8859ad6ec7ea807c0330ddf5559e13be5fb26c (patch) | |
tree | 68887107d0d40f1b22c7a7a07ccd9d7e4caf157a /chrome/browser | |
parent | 13dc122db24457653d57ff07791043d518eb05e7 (diff) | |
download | chromium_src-1f8859ad6ec7ea807c0330ddf5559e13be5fb26c.zip chromium_src-1f8859ad6ec7ea807c0330ddf5559e13be5fb26c.tar.gz chromium_src-1f8859ad6ec7ea807c0330ddf5559e13be5fb26c.tar.bz2 |
Change URLRequest to use a ref-counted buffer for actual IO.The ref-counting will prevent the deletion / reuse of memorywhile the buffer is actually being used by pending IO.This seems a very intrusive change, but at least we will be ableto make sure that it works without having to chase every singledestruction of an URLRequest to make sure that any pending IOwas cancelled, and also allows us to avoid blocking onthe object destruction.BUG=5325
Review URL: http://codereview.chromium.org/18390
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8603 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
30 files changed, 204 insertions, 119 deletions
diff --git a/chrome/browser/automation/url_request_slow_download_job.cc b/chrome/browser/automation/url_request_slow_download_job.cc index e1a2c84f0..71f71ca 100644 --- a/chrome/browser/automation/url_request_slow_download_job.cc +++ b/chrome/browser/automation/url_request_slow_download_job.cc @@ -72,7 +72,7 @@ void URLRequestSlowDownloadJob::StartAsync() { NotifyHeadersComplete(); } -bool URLRequestSlowDownloadJob::ReadRawData(char* buf, int buf_size, +bool URLRequestSlowDownloadJob::ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read) { if (LowerCaseEqualsASCII(kFinishDownloadUrl, request_->url().spec().c_str())) { @@ -83,7 +83,7 @@ bool URLRequestSlowDownloadJob::ReadRawData(char* buf, int buf_size, if (should_send_second_chunk_) { DCHECK(buf_size > kSecondDownloadSize); for (int i = 0; i < kSecondDownloadSize; ++i) { - buf[i] = '*'; + buf->data()[i] = '*'; } *bytes_read = kSecondDownloadSize; should_send_second_chunk_ = false; @@ -93,7 +93,7 @@ bool URLRequestSlowDownloadJob::ReadRawData(char* buf, int buf_size, if (first_download_size_remaining_ > 0) { int send_size = std::min(first_download_size_remaining_, buf_size); for (int i = 0; i < send_size; ++i) { - buf[i] = '*'; + buf->data()[i] = '*'; } *bytes_read = send_size; first_download_size_remaining_ -= send_size; diff --git a/chrome/browser/automation/url_request_slow_download_job.h b/chrome/browser/automation/url_request_slow_download_job.h index cf0156d..847121e 100644 --- a/chrome/browser/automation/url_request_slow_download_job.h +++ b/chrome/browser/automation/url_request_slow_download_job.h @@ -25,7 +25,7 @@ class URLRequestSlowDownloadJob : public URLRequestJob { virtual void Start(); virtual bool GetMimeType(std::string* mime_type); virtual void GetResponseInfo(net::HttpResponseInfo* info); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); static URLRequestJob* Factory(URLRequest* request, const std::string& scheme); diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc index f501764..7d8832e 100644 --- a/chrome/browser/chrome_plugin_host.cc +++ b/chrome/browser/chrome_plugin_host.cc @@ -145,7 +145,7 @@ class PluginRequestHandler : public PluginHelper, public URLRequest::Delegate { } PluginRequestHandler(ChromePluginLib* plugin, ScopableCPRequest* cprequest) - : PluginHelper(plugin), cprequest_(cprequest) { + : PluginHelper(plugin), cprequest_(cprequest), user_buffer_(NULL) { cprequest_->data = this; // see FromCPRequest(). URLRequestContext* context = CPBrowsingContextManager::Instance()-> @@ -163,6 +163,25 @@ class PluginRequestHandler : public PluginHelper, public URLRequest::Delegate { URLRequest* request() { return request_.get(); } + // Wraper of URLRequest::Read() + bool Read(char* dest, int dest_size, int *bytes_read) { + CHECK(!my_buffer_.get()); + // We'll use our own buffer until the read actually completes. + user_buffer_ = dest; + my_buffer_ = new net::IOBuffer(dest_size); + + if (request_->Read(my_buffer_, dest_size, bytes_read)) { + memcpy(dest, my_buffer_->data(), *bytes_read); + my_buffer_ = NULL; + return true; + } + + if (!request_->status().is_io_pending()) + my_buffer_ = NULL; + + return false; + } + // URLRequest::Delegate virtual void OnReceivedRedirect(URLRequest* request, const GURL& new_url) { plugin_->functions().response_funcs->received_redirect( @@ -178,16 +197,24 @@ class PluginRequestHandler : public PluginHelper, public URLRequest::Delegate { } virtual void OnReadCompleted(URLRequest* request, int bytes_read) { - // TODO(mpcomplete): better error codes - if (bytes_read < 0) + CHECK(my_buffer_.get()); + CHECK(user_buffer_); + if (bytes_read > 0) { + memcpy(user_buffer_, my_buffer_->data(), bytes_read); + } else if (bytes_read < 0) { + // TODO(mpcomplete): better error codes bytes_read = CPERR_FAILURE; + } + my_buffer_ = NULL; plugin_->functions().response_funcs->read_completed( - cprequest_.get(), bytes_read); + cprequest_.get(), bytes_read); } private: scoped_ptr<ScopableCPRequest> cprequest_; scoped_ptr<URLRequest> request_; + scoped_refptr<net::IOBuffer> my_buffer_; + char* user_buffer_; }; // This class manages plugins that want to handle UI commands. Right now, we @@ -614,7 +641,7 @@ int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) { CHECK(handler); int bytes_read; - if (handler->request()->Read(static_cast<char*>(buf), buf_size, &bytes_read)) + if (handler->Read(static_cast<char*>(buf), buf_size, &bytes_read)) return bytes_read; // 0 == CPERR_SUCESS if (handler->request()->status().is_io_pending()) diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.cc b/chrome/browser/dom_ui/chrome_url_data_manager.cc index a180280..ce533dd 100644 --- a/chrome/browser/dom_ui/chrome_url_data_manager.cc +++ b/chrome/browser/dom_ui/chrome_url_data_manager.cc @@ -42,7 +42,7 @@ class URLRequestChromeJob : public URLRequestJob { // URLRequestJob implementation. virtual void Start(); virtual void Kill(); - virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); virtual bool GetMimeType(std::string* mime_type); // Called by ChromeURLDataManager to notify us that the data blob is ready @@ -60,7 +60,7 @@ class URLRequestChromeJob : public URLRequestJob { // Do the actual copy from data_ (the data we're serving) into |buf|. // Separate from ReadRawData so we can handle async I/O. - void CompleteRead(char* buf, int buf_size, int* bytes_read); + void CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read); // The actual data we're serving. NULL until it's been fetched. scoped_refptr<RefCountedBytes> data_; @@ -70,7 +70,7 @@ class URLRequestChromeJob : public URLRequestJob { // For async reads, we keep around a pointer to the buffer that // we're reading into. - char* pending_buf_; + scoped_refptr<net::IOBuffer> pending_buf_; int pending_buf_size_; std::string mime_type_; @@ -249,7 +249,7 @@ URLRequestJob* ChromeURLDataManager::Factory(URLRequest* request, } URLRequestChromeJob::URLRequestChromeJob(URLRequest* request) - : URLRequestJob(request), data_offset_(0), pending_buf_(NULL) {} + : URLRequestJob(request), data_offset_(0) {} URLRequestChromeJob::~URLRequestChromeJob() { } @@ -278,9 +278,10 @@ void URLRequestChromeJob::DataAvailable(RefCountedBytes* bytes) { data_ = bytes; int bytes_read; - if (pending_buf_) { + if (pending_buf_.get()) { CompleteRead(pending_buf_, pending_buf_size_, &bytes_read); NotifyReadComplete(bytes_read); + pending_buf_ = NULL; } } else { // The request failed. @@ -288,10 +289,11 @@ void URLRequestChromeJob::DataAvailable(RefCountedBytes* bytes) { } } -bool URLRequestChromeJob::ReadRawData(char* buf, int buf_size, +bool URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) { if (!data_.get()) { SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0)); + DCHECK(!pending_buf_.get()); pending_buf_ = buf; pending_buf_size_ = buf_size; return false; // Tell the caller we're still waiting for data. @@ -302,13 +304,13 @@ bool URLRequestChromeJob::ReadRawData(char* buf, int buf_size, return true; } -void URLRequestChromeJob::CompleteRead(char* buf, int buf_size, +void URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read) { int remaining = static_cast<int>(data_->data.size()) - data_offset_; if (buf_size > remaining) buf_size = remaining; if (buf_size > 0) { - memcpy(buf, &data_->data[0] + data_offset_, buf_size); + memcpy(buf->data(), &data_->data[0] + data_offset_, buf_size); data_offset_ += buf_size; } *bytes_read = buf_size; diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc index 70d733d..5d7b5e5c 100644 --- a/chrome/browser/download/download_file.cc +++ b/chrome/browser/download/download_file.cc @@ -23,6 +23,7 @@ #include "chrome/common/win_util.h" #include "chrome/common/win_safe_util.h" #include "googleurl/src/gurl.h" +#include "net/base/io_buffer.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context.h" @@ -265,11 +266,11 @@ void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { DownloadFile* download = LookupDownload(id); for (size_t i = 0; i < contents.size(); ++i) { - char* data = contents[i].first; + net::IOBuffer* data = contents[i].first; const int data_len = contents[i].second; if (download) - download->AppendDataToFile(data, data_len); - delete [] data; + download->AppendDataToFile(data->data(), data_len); + data->Release(); } if (download) { diff --git a/chrome/browser/download/download_file.h b/chrome/browser/download/download_file.h index ea74318..f1ffcea 100644 --- a/chrome/browser/download/download_file.h +++ b/chrome/browser/download/download_file.h @@ -52,6 +52,9 @@ #include "base/timer.h" #include "chrome/browser/history/download_types.h" +namespace net { +class IOBuffer; +} class DownloadManager; class FilePath; class GURL; @@ -70,7 +73,7 @@ class URLRequestContext; struct DownloadBuffer { Lock lock; - typedef std::pair<char *, int> Contents; + typedef std::pair<net::IOBuffer*, int> Contents; std::vector<Contents> contents; }; diff --git a/chrome/browser/download/save_file_manager.cc b/chrome/browser/download/save_file_manager.cc index fbf5782..64984de 100644 --- a/chrome/browser/download/save_file_manager.cc +++ b/chrome/browser/download/save_file_manager.cc @@ -25,6 +25,7 @@ #include "chrome/common/win_safe_util.h" #include "googleurl/src/gurl.h" #include "net/base/net_util.h" +#include "net/base/io_buffer.h" #include "net/url_request/url_request_context.h" SaveFileManager::SaveFileManager(MessageLoop* ui_loop, @@ -271,12 +272,12 @@ void SaveFileManager::StartSave(SaveFileCreateInfo* info) { // thread). We may receive a few more updates before the IO thread gets the // cancel message. We just delete the data since the SaveFile has been deleted. void SaveFileManager::UpdateSaveProgress(int save_id, - char* data, + net::IOBuffer* data, int data_len) { DCHECK(MessageLoop::current() == GetSaveLoop()); SaveFile* save_file = LookupSaveFile(save_id); if (save_file) { - bool write_success = save_file->AppendDataToFile(data, data_len); + bool write_success = save_file->AppendDataToFile(data->data(), data_len); ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &SaveFileManager::OnUpdateSaveProgress, @@ -284,7 +285,7 @@ void SaveFileManager::UpdateSaveProgress(int save_id, save_file->bytes_so_far(), write_success)); } - delete [] data; + data->Release(); } // The IO thread will call this when saving is completed or it got error when diff --git a/chrome/browser/download/save_file_manager.h b/chrome/browser/download/save_file_manager.h index 8bd6e89..cf29e1c 100644 --- a/chrome/browser/download/save_file_manager.h +++ b/chrome/browser/download/save_file_manager.h @@ -66,6 +66,9 @@ #include "base/thread.h" #include "chrome/browser/download/save_types.h" +namespace net { +class IOBuffer; +} class GURL; class SaveFile; class SavePackage; @@ -101,7 +104,7 @@ class SaveFileManager // Notifications sent from the IO thread and run on the file thread: void StartSave(SaveFileCreateInfo* info); - void UpdateSaveProgress(int save_id, char* data, int size); + void UpdateSaveProgress(int save_id, net::IOBuffer* data, int size); void SaveFinished(int save_id, std::wstring save_url, int render_process_id, bool is_success); diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index 1127017..1eea9e5 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -31,6 +31,7 @@ #include "chrome/common/pref_service.h" #include "chrome/common/stl_util-inl.h" #include "chrome/common/win_util.h" +#include "net/base/io_buffer.h" #include "net/base/mime_util.h" #include "net/base/net_util.h" #include "net/url_request/url_request_context.h" @@ -812,8 +813,8 @@ void SavePackage::OnReceivedSerializedHtmlData(const GURL& frame_url, if (!data.empty()) { // Prepare buffer for saving HTML data. - char* new_data = static_cast<char*>(new char[data.size()]); - memcpy(new_data, data.data(), data.size()); + net::IOBuffer* new_data = new net::IOBuffer(data.size()); + memcpy(new_data->data(), data.data(), data.size()); // Call write file functionality in file thread. file_manager_->GetSaveLoop()->PostTask(FROM_HERE, diff --git a/chrome/browser/net/url_fetcher.cc b/chrome/browser/net/url_fetcher.cc index b7ea8cd..9e41f22 100644 --- a/chrome/browser/net/url_fetcher.cc +++ b/chrome/browser/net/url_fetcher.cc @@ -11,6 +11,9 @@ #include "chrome/browser/chrome_thread.h" #include "googleurl/src/gurl.h" #include "net/base/load_flags.h" +#include "net/base/io_buffer.h" + +static const int kBufferSize = 4096; URLFetcher::URLFetcher(const GURL& url, RequestType request_type, @@ -36,6 +39,7 @@ URLFetcher::Core::Core(URLFetcher* fetcher, request_(NULL), load_flags_(net::LOAD_NORMAL), response_code_(-1), + buffer_(new net::IOBuffer(kBufferSize)), protect_entry_(URLFetcherProtectManager::GetInstance()->Register( original_url_.host())), num_retries_(0) { @@ -71,7 +75,7 @@ void URLFetcher::Core::OnResponseStarted(URLRequest* request) { // completed immediately, without trying to read any data back (all we care // about is the response code and headers, which we already have). if (request_->status().is_success() && (request_type_ != HEAD)) - request_->Read(buffer_, sizeof(buffer_), &bytes_read); + request_->Read(buffer_, kBufferSize, &bytes_read); OnReadCompleted(request_, bytes_read); } @@ -84,8 +88,8 @@ void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) { do { if (!request_->status().is_success() || bytes_read <= 0) break; - data_.append(buffer_, bytes_read); - } while (request_->Read(buffer_, sizeof(buffer_), &bytes_read)); + data_.append(buffer_->data(), bytes_read); + } while (request_->Read(buffer_, kBufferSize, &bytes_read)); if (request_->status().is_success()) request_->GetResponseCookies(&cookies_); diff --git a/chrome/browser/net/url_fetcher.h b/chrome/browser/net/url_fetcher.h index 7e4c132..044e61b 100644 --- a/chrome/browser/net/url_fetcher.h +++ b/chrome/browser/net/url_fetcher.h @@ -185,7 +185,8 @@ class URLFetcher { int load_flags_; // Flags for the load operation int response_code_; // HTTP status code for the request std::string data_; // Results of the request - char buffer_[4096]; // Read buffer + scoped_refptr<net::IOBuffer> buffer_; + // Read buffer scoped_refptr<URLRequestContext> request_context_; // Cookie/cache info for the request ResponseCookies cookies_; // Response cookies diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 7c272a5..aeff2d0 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -36,6 +36,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/win_util.h" #include "net/base/cookie_monster.h" +#include "net/base/io_buffer.h" #include "net/proxy/proxy_service.h" #include "net/url_request/url_request.h" #include "sandbox/src/sandbox.h" @@ -127,7 +128,7 @@ class PluginDownloadUrlHelper : public URLRequest::Delegate { // The full path of the downloaded file. std::wstring download_file_path_; // The buffer passed off to URLRequest::Read. - char download_file_buffer_[kDownloadFileBufferSize]; + scoped_refptr<net::IOBuffer> download_file_buffer_; // The window handle for sending the WM_COPYDATA notification, // indicating that the download completed. HWND download_file_caller_window_; @@ -142,12 +143,13 @@ PluginDownloadUrlHelper::PluginDownloadUrlHelper( const std::string& download_url, int source_pid, HWND caller_window) : download_url_(download_url), - download_file_caller_window_(caller_window), - download_source_pid_(source_pid), download_file_request_(NULL), - download_file_(INVALID_HANDLE_VALUE) { + download_file_(INVALID_HANDLE_VALUE), + download_file_buffer_(new net::IOBuffer(kDownloadFileBufferSize)), + download_file_caller_window_(caller_window), + download_source_pid_(source_pid) { DCHECK(::IsWindow(caller_window)); - memset(download_file_buffer_, 0, arraysize(download_file_buffer_)); + memset(download_file_buffer_->data(), 0, kDownloadFileBufferSize); } PluginDownloadUrlHelper::~PluginDownloadUrlHelper() { @@ -210,7 +212,7 @@ void PluginDownloadUrlHelper::OnResponseStarted(URLRequest* request) { } else { // Initiate a read. int bytes_read = 0; - if (!request->Read(download_file_buffer_, arraysize(download_file_buffer_), + if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, &bytes_read)) { // If the error is not an IO pending, then we're done // reading. @@ -238,7 +240,8 @@ void PluginDownloadUrlHelper::OnReadCompleted(URLRequest* request, while (request->status().is_success()) { unsigned long bytes_written = 0; - BOOL write_result = WriteFile(download_file_, download_file_buffer_, + BOOL write_result = WriteFile(download_file_, + download_file_buffer_->data(), request_bytes_read, &bytes_written, NULL); DCHECK(!write_result || (bytes_written == request_bytes_read)); @@ -249,7 +252,7 @@ void PluginDownloadUrlHelper::OnReadCompleted(URLRequest* request, // Start reading request_bytes_read = 0; - if (!request->Read(download_file_buffer_, arraysize(download_file_buffer_), + if (!request->Read(download_file_buffer_, kDownloadFileBufferSize, &request_bytes_read)) { if (!request->status().is_io_pending()) { // If the error is not an IO pending, then we're done diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index a59f61e..814415e 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -5,8 +5,31 @@ #include "chrome/browser/renderer_host/async_resource_handler.h" #include "base/process.h" +#include "net/base/io_buffer.h" + +SharedIOBuffer* AsyncResourceHandler::spare_read_buffer_; + +// Our version of IOBuffer that uses shared memory. +class SharedIOBuffer : public net::IOBuffer { + public: + SharedIOBuffer(int buffer_size) : net::IOBuffer(NULL), ok_(false) { + if (shared_memory_.Create(std::wstring(), false, false, buffer_size) && + shared_memory_.Map(buffer_size)) { + ok_ = true; + data_ = reinterpret_cast<char*>(shared_memory_.memory()); + } + } + ~SharedIOBuffer() { + data_ = NULL; + } -base::SharedMemory* AsyncResourceHandler::spare_read_buffer_; + base::SharedMemory* shared_memory() { return &shared_memory_; } + bool ok() { return ok_; } + + private: + base::SharedMemory shared_memory_; + bool ok_; +}; AsyncResourceHandler::AsyncResourceHandler( ResourceDispatcherHost::Receiver* receiver, @@ -44,22 +67,19 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id, return true; } -bool AsyncResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool AsyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(min_size == -1); static const int kReadBufSize = 32768; if (spare_read_buffer_) { - read_buffer_.reset(spare_read_buffer_); + read_buffer_ = spare_read_buffer_; spare_read_buffer_ = NULL; } else { - read_buffer_.reset(new base::SharedMemory); - if (!read_buffer_->Create(std::wstring(), false, false, kReadBufSize)) - return false; - if (!read_buffer_->Map(kReadBufSize)) + read_buffer_ = new SharedIOBuffer(kReadBufSize); + if (!read_buffer_->ok()) return false; } - *buf = static_cast<char*>(read_buffer_->memory()); + *buf = read_buffer_.get(); *buf_size = kReadBufSize; return true; } @@ -75,7 +95,7 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { } base::SharedMemoryHandle handle; - if (!read_buffer_->GiveToProcess(render_process_, &handle)) { + if (!read_buffer_->shared_memory()->GiveToProcess(render_process_, &handle)) { // We wrongfully incremented the pending data count. Fake an ACK message // to fix this. We can't move this call above the WillSendData because // it's killing our read_buffer_, and we don't want that when we pause @@ -97,15 +117,14 @@ bool AsyncResourceHandler::OnResponseCompleted(int request_id, // If we still have a read buffer, then see about caching it for later... if (spare_read_buffer_) { - read_buffer_.reset(); - } else if (read_buffer_.get() && read_buffer_->memory()) { - spare_read_buffer_ = read_buffer_.release(); + read_buffer_ = NULL; + } else if (read_buffer_.get() && read_buffer_->data()) { + read_buffer_.swap(&spare_read_buffer_); } return true; } // static void AsyncResourceHandler::GlobalCleanup() { - delete spare_read_buffer_; spare_read_buffer_ = NULL; } diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h index 618e518..e966a80 100644 --- a/chrome/browser/renderer_host/async_resource_handler.h +++ b/chrome/browser/renderer_host/async_resource_handler.h @@ -9,9 +9,7 @@ #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_handler.h" -namespace base { -class SharedMemory; -} +class SharedIOBuffer; // Used to complete an asynchronous resource request in response to resource // load events from the resource dispatcher host. @@ -28,7 +26,8 @@ class AsyncResourceHandler : public ResourceHandler { bool OnUploadProgress(int request_id, uint64 position, uint64 size); bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); @@ -38,9 +37,9 @@ class AsyncResourceHandler : public ResourceHandler { // When reading, we don't know if we are going to get EOF (0 bytes read), so // we typically have a buffer that we allocated but did not use. We keep // this buffer around for the next read as a small optimization. - static base::SharedMemory* spare_read_buffer_; + static SharedIOBuffer* spare_read_buffer_; - scoped_ptr<base::SharedMemory> read_buffer_; + scoped_refptr<SharedIOBuffer> read_buffer_; ResourceDispatcherHost::Receiver* receiver_; int render_process_host_id_; int routing_id_; diff --git a/chrome/browser/renderer_host/buffered_resource_handler.cc b/chrome/browser/renderer_host/buffered_resource_handler.cc index ea7d69d..458dc8c 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.cc +++ b/chrome/browser/renderer_host/buffered_resource_handler.cc @@ -8,9 +8,13 @@ #include "net/base/mime_sniffer.h" #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "net/base/mime_sniffer.h" +#include "net/base/io_buffer.h" namespace { +const int kMaxBytesToSniff = 512; + void RecordSnifferMetrics(bool sniffing_blocked, bool we_would_like_to_sniff, const std::string& mime_type) { @@ -71,13 +75,13 @@ bool BufferedResourceHandler::OnResponseCompleted( // We'll let the original event handler provide a buffer, and reuse it for // subsequent reads until we're done buffering. -bool BufferedResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { if (buffering_) { - *buf = read_buffer_ + bytes_read_; - *buf_size = read_buffer_size_ - bytes_read_; - DCHECK(*buf_size > 0); + DCHECK(!my_buffer_.get()); + my_buffer_ = new net::IOBuffer(kMaxBytesToSniff); + *buf = my_buffer_.get(); + *buf_size = kMaxBytesToSniff; return true; } @@ -87,6 +91,7 @@ bool BufferedResourceHandler::OnWillRead(int request_id, bool ret = real_handler_->OnWillRead(request_id, buf, buf_size, min_size); read_buffer_ = *buf; read_buffer_size_ = *buf_size; + DCHECK(read_buffer_size_ >= kMaxBytesToSniff * 2); bytes_read_ = 0; return ret; } @@ -168,6 +173,12 @@ bool BufferedResourceHandler::ShouldBuffer(const GURL& url, bool BufferedResourceHandler::KeepBuffering(int bytes_read) { DCHECK(read_buffer_); + if (my_buffer_) { + // We are using our own buffer to read, update the main buffer. + CHECK(bytes_read + bytes_read_ < read_buffer_size_); + memcpy(read_buffer_->data() + bytes_read_, my_buffer_->data(), bytes_read); + my_buffer_ = NULL; + } bytes_read_ += bytes_read; finished_ = (bytes_read == 0); @@ -175,12 +186,12 @@ bool BufferedResourceHandler::KeepBuffering(int bytes_read) { std::string type_hint, new_type; request_->GetMimeType(&type_hint); - if (!net::SniffMimeType(read_buffer_, bytes_read_, request_->url(), - type_hint, &new_type)) { + if (!net::SniffMimeType(read_buffer_->data(), bytes_read_, + request_->url(), type_hint, &new_type)) { // SniffMimeType() returns false if there is not enough data to determine // the mime type. However, even if it returns false, it returns a new type // that is probably better than the current one. - DCHECK(bytes_read_ < 512 /*kMaxBytesToSniff*/); + DCHECK(bytes_read_ < kMaxBytesToSniff); if (!finished_) { buffering_ = true; return true; @@ -243,11 +254,11 @@ bool BufferedResourceHandler::CompleteResponseStarted(int request_id, if (bytes_read_) { // a Read has already occurred and we need to copy the data into the // EventHandler. - char *buf = NULL; + net::IOBuffer* buf = NULL; int buf_len = 0; download_handler->OnWillRead(request_id, &buf, &buf_len, bytes_read_); CHECK((buf_len >= bytes_read_) && (bytes_read_ >= 0)); - memcpy(buf, read_buffer_, bytes_read_); + memcpy(buf->data(), read_buffer_->data(), bytes_read_); } // Update the renderer with the response headers which will cause it to // cancel the request. diff --git a/chrome/browser/renderer_host/buffered_resource_handler.h b/chrome/browser/renderer_host/buffered_resource_handler.h index 0b832a9..a612722 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.h +++ b/chrome/browser/renderer_host/buffered_resource_handler.h @@ -22,7 +22,8 @@ class BufferedResourceHandler : public ResourceHandler { bool OnUploadProgress(int request_id, uint64 position, uint64 size); bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); @@ -48,7 +49,8 @@ class BufferedResourceHandler : public ResourceHandler { scoped_refptr<ResourceResponse> response_; ResourceDispatcherHost* host_; URLRequest* request_; - char* read_buffer_; + scoped_refptr<net::IOBuffer> read_buffer_; + scoped_refptr<net::IOBuffer> my_buffer_; int read_buffer_size_; int bytes_read_; bool sniff_content_; diff --git a/chrome/browser/renderer_host/cross_site_resource_handler.cc b/chrome/browser/renderer_host/cross_site_resource_handler.cc index a172352..363d451 100644 --- a/chrome/browser/renderer_host/cross_site_resource_handler.cc +++ b/chrome/browser/renderer_host/cross_site_resource_handler.cc @@ -114,9 +114,8 @@ bool CrossSiteResourceHandler::OnResponseStarted(int request_id, return true; } -bool CrossSiteResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool CrossSiteResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); } diff --git a/chrome/browser/renderer_host/cross_site_resource_handler.h b/chrome/browser/renderer_host/cross_site_resource_handler.h index 7801352..7d57c76 100644 --- a/chrome/browser/renderer_host/cross_site_resource_handler.h +++ b/chrome/browser/renderer_host/cross_site_resource_handler.h @@ -24,7 +24,8 @@ class CrossSiteResourceHandler : public ResourceHandler { bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); diff --git a/chrome/browser/renderer_host/download_resource_handler.cc b/chrome/browser/renderer_host/download_resource_handler.cc index 13e7457..01704e7 100644 --- a/chrome/browser/renderer_host/download_resource_handler.cc +++ b/chrome/browser/renderer_host/download_resource_handler.cc @@ -7,6 +7,7 @@ #include "chrome/browser/download/download_file.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "net/base/io_buffer.h" DownloadResourceHandler::DownloadResourceHandler(ResourceDispatcherHost* rdh, int render_process_host_id, @@ -20,7 +21,6 @@ DownloadResourceHandler::DownloadResourceHandler(ResourceDispatcherHost* rdh, global_id_(ResourceDispatcherHost::GlobalRequestID(render_process_host_id, request_id)), render_view_id_(render_view_id), - read_buffer_(NULL), url_(UTF8ToWide(url)), content_length_(0), download_manager_(manager), @@ -72,15 +72,14 @@ bool DownloadResourceHandler::OnResponseStarted(int request_id, // Create a new buffer, which will be handed to the download thread for file // writing and deletion. -bool DownloadResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool DownloadResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(buf && buf_size); if (!read_buffer_) { *buf_size = min_size < 0 ? kReadBufSize : min_size; - read_buffer_ = new char[*buf_size]; + read_buffer_ = new net::IOBuffer(*buf_size); } - *buf = read_buffer_; + *buf = read_buffer_.get(); return true; } @@ -91,7 +90,11 @@ bool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { DCHECK(read_buffer_); AutoLock auto_lock(buffer_->lock); bool need_update = buffer_->contents.empty(); - buffer_->contents.push_back(std::make_pair(read_buffer_, *bytes_read)); + + // We are passing ownership of this buffer to the download file manager. + net::IOBuffer* buffer = NULL; + read_buffer_.swap(&buffer); + buffer_->contents.push_back(std::make_pair(buffer, *bytes_read)); if (need_update) { download_manager_->file_loop()->PostTask(FROM_HERE, NewRunnableMethod(download_manager_, @@ -99,7 +102,6 @@ bool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { download_id_, buffer_)); } - read_buffer_ = NULL; // We schedule a pause outside of the read loop if there is too much file // writing work to do. @@ -117,7 +119,7 @@ bool DownloadResourceHandler::OnResponseCompleted( &DownloadFileManager::DownloadFinished, download_id_, buffer_)); - delete [] read_buffer_; + read_buffer_ = NULL; // 'buffer_' is deleted by the DownloadFileManager. buffer_ = NULL; diff --git a/chrome/browser/renderer_host/download_resource_handler.h b/chrome/browser/renderer_host/download_resource_handler.h index b666df6..0dbeef0 100644 --- a/chrome/browser/renderer_host/download_resource_handler.h +++ b/chrome/browser/renderer_host/download_resource_handler.h @@ -32,7 +32,8 @@ class DownloadResourceHandler : public ResourceHandler { // Create a new buffer, which will be handed to the download thread for file // writing and deletion. - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); @@ -53,7 +54,7 @@ class DownloadResourceHandler : public ResourceHandler { int download_id_; ResourceDispatcherHost::GlobalRequestID global_id_; int render_view_id_; - char* read_buffer_; + scoped_refptr<net::IOBuffer> read_buffer_; std::string content_disposition_; std::wstring url_; int64 content_length_; diff --git a/chrome/browser/renderer_host/download_throttling_resource_handler.cc b/chrome/browser/renderer_host/download_throttling_resource_handler.cc index 07b8164..ea4fdbb 100644 --- a/chrome/browser/renderer_host/download_throttling_resource_handler.cc +++ b/chrome/browser/renderer_host/download_throttling_resource_handler.cc @@ -5,6 +5,7 @@ #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" #include "chrome/browser/renderer_host/download_resource_handler.h" +#include "net/base/io_buffer.h" DownloadThrottlingResourceHandler::DownloadThrottlingResourceHandler( ResourceDispatcherHost* host, @@ -57,7 +58,7 @@ bool DownloadThrottlingResourceHandler::OnResponseStarted( } bool DownloadThrottlingResourceHandler::OnWillRead(int request_id, - char** buf, + net::IOBuffer** buf, int* buf_size, int min_size) { if (download_handler_.get()) @@ -68,7 +69,7 @@ bool DownloadThrottlingResourceHandler::OnWillRead(int request_id, DCHECK(!tmp_buffer_.get()); if (min_size < 0) min_size = 1024; - tmp_buffer_.reset(new char[min_size]); + tmp_buffer_ = new net::IOBuffer(min_size); *buf = tmp_buffer_.get(); *buf_size = min_size; return true; @@ -132,14 +133,14 @@ void DownloadThrottlingResourceHandler::ContinueDownload() { void DownloadThrottlingResourceHandler::CopyTmpBufferToDownloadHandler() { // Copy over the tmp buffer. - char* buffer; + net::IOBuffer* buffer; int buf_size; if (download_handler_->OnWillRead(request_id_, &buffer, &buf_size, tmp_buffer_length_)) { CHECK(buf_size >= tmp_buffer_length_); - memcpy(buffer, tmp_buffer_.get(), tmp_buffer_length_); + memcpy(buffer->data(), tmp_buffer_->data(), tmp_buffer_length_); download_handler_->OnReadCompleted(request_id_, &tmp_buffer_length_); } tmp_buffer_length_ = 0; - tmp_buffer_.reset(); + tmp_buffer_ = NULL; } diff --git a/chrome/browser/renderer_host/download_throttling_resource_handler.h b/chrome/browser/renderer_host/download_throttling_resource_handler.h index 177f4fd..97b2942 100644 --- a/chrome/browser/renderer_host/download_throttling_resource_handler.h +++ b/chrome/browser/renderer_host/download_throttling_resource_handler.h @@ -40,9 +40,7 @@ class DownloadThrottlingResourceHandler uint64 size); virtual bool OnRequestRedirected(int request_id, const GURL& url); virtual bool OnResponseStarted(int request_id, ResourceResponse* response); - virtual bool OnWillRead(int request_id, - char** buf, - int* buf_size, + virtual bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, int min_size); virtual bool OnReadCompleted(int request_id, int* bytes_read); virtual bool OnResponseCompleted(int request_id, @@ -72,7 +70,7 @@ class DownloadThrottlingResourceHandler // If we're created by way of BufferedEventHandler we'll get one request for // a buffer. This is that buffer. - scoped_array<char> tmp_buffer_; + scoped_refptr<net::IOBuffer> tmp_buffer_; int tmp_buffer_length_; // If true the next call to OnReadCompleted is ignored. This is used if we're diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 261d1c1..2864d88 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -928,7 +928,7 @@ bool ResourceDispatcherHost::Read(URLRequest* request, int* bytes_read) { ExtraRequestInfo* info = ExtraInfoForRequest(request); DCHECK(!info->is_paused); - char* buf; + net::IOBuffer* buf; int buf_size; if (!info->resource_handler->OnWillRead(info->request_id, &buf, &buf_size, -1)) { diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h index a6955c7..9813094 100644 --- a/chrome/browser/renderer_host/resource_handler.h +++ b/chrome/browser/renderer_host/resource_handler.h @@ -49,7 +49,7 @@ class ResourceHandler : public base::RefCounted<ResourceHandler> { // out-params. This call will be followed by either OnReadCompleted or // OnResponseCompleted, at which point the buffer may be recycled. virtual bool OnWillRead(int request_id, - char** buf, + net::IOBuffer** buf, int* buf_size, int min_size) = 0; diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc index 3ca7b38..7ee4661 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.cc +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.cc @@ -77,7 +77,7 @@ void SafeBrowsingResourceHandler::OnGetHashTimeout() { } bool SafeBrowsingResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, + net::IOBuffer** buf, int* buf_size, int min_size) { if (in_safe_browsing_check_ && pause_time_.is_null()) { pause_time_ = base::Time::Now(); diff --git a/chrome/browser/renderer_host/safe_browsing_resource_handler.h b/chrome/browser/renderer_host/safe_browsing_resource_handler.h index 244df8b..92e0040 100644 --- a/chrome/browser/renderer_host/safe_browsing_resource_handler.h +++ b/chrome/browser/renderer_host/safe_browsing_resource_handler.h @@ -28,7 +28,8 @@ class SafeBrowsingResourceHandler : public ResourceHandler, bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); void OnGetHashTimeout(); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); diff --git a/chrome/browser/renderer_host/save_file_resource_handler.cc b/chrome/browser/renderer_host/save_file_resource_handler.cc index 420b28a..2520961 100644 --- a/chrome/browser/renderer_host/save_file_resource_handler.cc +++ b/chrome/browser/renderer_host/save_file_resource_handler.cc @@ -5,6 +5,7 @@ #include "chrome/browser/renderer_host/save_file_resource_handler.h" #include "chrome/browser/download/save_file_manager.h" +#include "net/base/io_buffer.h" SaveFileResourceHandler::SaveFileResourceHandler(int render_process_host_id, int render_view_id, @@ -13,7 +14,6 @@ SaveFileResourceHandler::SaveFileResourceHandler(int render_process_host_id, : save_id_(-1), render_process_id_(render_process_host_id), render_view_id_(render_view_id), - read_buffer_(NULL), url_(UTF8ToWide(url)), content_length_(0), save_manager_(manager) { @@ -46,27 +46,28 @@ bool SaveFileResourceHandler::OnResponseStarted(int request_id, return true; } -bool SaveFileResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, - int min_size) { +bool SaveFileResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(buf && buf_size); if (!read_buffer_) { *buf_size = min_size < 0 ? kReadBufSize : min_size; - read_buffer_ = new char[*buf_size]; + read_buffer_ = new net::IOBuffer(*buf_size); } - *buf = read_buffer_; + *buf = read_buffer_.get(); return true; } bool SaveFileResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { DCHECK(read_buffer_); + // We are passing ownership of this buffer to the save file manager. + net::IOBuffer* buffer = NULL; + read_buffer_.swap(&buffer); save_manager_->GetSaveLoop()->PostTask(FROM_HERE, NewRunnableMethod(save_manager_, &SaveFileManager::UpdateSaveProgress, save_id_, - read_buffer_, + buffer, *bytes_read)); - read_buffer_ = NULL; return true; } @@ -80,6 +81,6 @@ bool SaveFileResourceHandler::OnResponseCompleted( url_, render_process_id_, status.is_success() && !status.is_io_pending())); - delete [] read_buffer_; + read_buffer_ = NULL; return true; } diff --git a/chrome/browser/renderer_host/save_file_resource_handler.h b/chrome/browser/renderer_host/save_file_resource_handler.h index 87f06ae..30fc074 100644 --- a/chrome/browser/renderer_host/save_file_resource_handler.h +++ b/chrome/browser/renderer_host/save_file_resource_handler.h @@ -28,7 +28,8 @@ class SaveFileResourceHandler : public ResourceHandler { // Creates a new buffer, which will be handed to the download thread for file // writing and deletion. - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); // Passes the buffer to the download file writer. bool OnReadCompleted(int request_id, int* bytes_read); @@ -50,7 +51,7 @@ class SaveFileResourceHandler : public ResourceHandler { int save_id_; int render_process_id_; int render_view_id_; - char* read_buffer_; + scoped_refptr<net::IOBuffer> read_buffer_; std::string content_disposition_; std::wstring url_; std::wstring final_url_; diff --git a/chrome/browser/renderer_host/sync_resource_handler.cc b/chrome/browser/renderer_host/sync_resource_handler.cc index aace1c1..a30f10f 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.cc +++ b/chrome/browser/renderer_host/sync_resource_handler.cc @@ -8,7 +8,8 @@ SyncResourceHandler::SyncResourceHandler( ResourceDispatcherHost::Receiver* receiver, const GURL& url, IPC::Message* result_message) - : receiver_(receiver), + : read_buffer_(new net::IOBuffer(kReadBufSize)), + receiver_(receiver), result_message_(result_message) { result_.final_url = url; result_.filter_policy = FilterPolicy::DONT_FILTER; @@ -29,10 +30,10 @@ bool SyncResourceHandler::OnResponseStarted(int request_id, return true; } -bool SyncResourceHandler::OnWillRead(int request_id, - char** buf, int* buf_size, int min_size) { +bool SyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, + int* buf_size, int min_size) { DCHECK(min_size == -1); - *buf = read_buffer_; + *buf = read_buffer_.get(); *buf_size = kReadBufSize; return true; } @@ -40,7 +41,7 @@ bool SyncResourceHandler::OnWillRead(int request_id, bool SyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { if (!*bytes_read) return true; - result_.data.append(read_buffer_, *bytes_read); + result_.data.append(read_buffer_->data(), *bytes_read); return true; } diff --git a/chrome/browser/renderer_host/sync_resource_handler.h b/chrome/browser/renderer_host/sync_resource_handler.h index 81a6078..012ab9e 100644 --- a/chrome/browser/renderer_host/sync_resource_handler.h +++ b/chrome/browser/renderer_host/sync_resource_handler.h @@ -7,6 +7,7 @@ #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/renderer_host/resource_handler.h" +#include "net/base/io_buffer.h" // Used to complete a synchronous resource request in response to resource load // events from the resource dispatcher host. @@ -18,13 +19,14 @@ class SyncResourceHandler : public ResourceHandler { bool OnRequestRedirected(int request_id, const GURL& new_url); bool OnResponseStarted(int request_id, ResourceResponse* response); - bool OnWillRead(int request_id, char** buf, int* buf_size, int min_size); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); bool OnReadCompleted(int request_id, int* bytes_read); bool OnResponseCompleted(int request_id, const URLRequestStatus& status); private: enum { kReadBufSize = 3840 }; - char read_buffer_[kReadBufSize]; + scoped_refptr<net::IOBuffer> read_buffer_; ViewHostMsg_SyncLoad_Result result_; ResourceDispatcherHost::Receiver* receiver_; |