diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-30 23:05:15 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-30 23:05:15 +0000 |
commit | 21ae1f956c163bc0e3b3e239b5c027a7ac93ae7f (patch) | |
tree | 4eee3fe37f83559b1a97f75dcdef0337b68e2cf1 /chrome/browser/renderer_host | |
parent | 0436fcd542e8ce436fe9395a64cc03fa369276b1 (diff) | |
download | chromium_src-21ae1f956c163bc0e3b3e239b5c027a7ac93ae7f.zip chromium_src-21ae1f956c163bc0e3b3e239b5c027a7ac93ae7f.tar.gz chromium_src-21ae1f956c163bc0e3b3e239b5c027a7ac93ae7f.tar.bz2 |
Asynchronously open the temp file used for Pepper StreamToFile, and delete the
temp file once we are done with it.
We observe ResourceHandle::OnRequestClosed as a signal of when we should delete
the temp file. This corresponds to the WebURLLoader being closed (or
canceled).
This patch also includes some helpers:
base/scoped_callback_factory.h
This class makes it easy to allocate Callbacks that hold a weak reference
back to the owning class. It works just like ScopedRunnableMethodFactory
but for Callbacks instead of RunnableMethods.
base/platform_file.h
Added a PassPlatformFile class that is useful for cases where a callback may
decide not to take ownership of a PlatformFile (as can happen when using
ScopedCallbackFactory).
chrome/file_system_proxy.{h,cc}
This class provides static methods for executing file system commands on the
FILE thread. It routes callbacks back to the originating thread to deliver
results (file handles, etc.). Note: this file declares a few functions that
are not yet used. I anticipate that we'll make use of these and add more
functions here to support the Pepper and OWP FileSystem APIs.
chrome/chrome_thread_relay.{h,cc}
This class is a helper class for proxying calls over to a background
ChromeThread and then returning results to the originating ChromeThread.
R=brettw
BUG=49789
TEST=(more to be added in third_party/ppapi/tests)
Review URL: http://codereview.chromium.org/2878062
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54402 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r-- | chrome/browser/renderer_host/redirect_to_file_resource_handler.cc | 58 | ||||
-rw-r--r-- | chrome/browser/renderer_host/redirect_to_file_resource_handler.h | 12 |
2 files changed, 53 insertions, 17 deletions
diff --git a/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc b/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc index 4f523b7..11beb73 100644 --- a/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc +++ b/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc @@ -5,9 +5,13 @@ #include "chrome/browser/renderer_host/redirect_to_file_resource_handler.h" #include "base/file_util.h" +#include "base/logging.h" #include "base/platform_file.h" +#include "base/task.h" +#include "chrome/browser/file_system_proxy.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/common/resource_response.h" +#include "net/base/file_stream.h" #include "net/base/io_buffer.h" #include "net/base/mime_sniffer.h" #include "net/base/net_errors.h" @@ -19,7 +23,8 @@ RedirectToFileResourceHandler::RedirectToFileResourceHandler( ResourceHandler* next_handler, int process_id, ResourceDispatcherHost* host) - : host_(host), + : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + host_(host), next_handler_(next_handler), process_id_(process_id), request_id_(-1), @@ -50,8 +55,7 @@ bool RedirectToFileResourceHandler::OnResponseStarted( int request_id, ResourceResponse* response) { if (response->response_head.status.is_success()) { - // TODO(darin): Move this file creation to a background thread. - file_util::CreateTemporaryFile(&file_path_); + DCHECK(!file_path_.empty()); response->response_head.download_file_path = file_path_; } return next_handler_->OnResponseStarted(request_id, response); @@ -60,6 +64,17 @@ bool RedirectToFileResourceHandler::OnResponseStarted( bool RedirectToFileResourceHandler::OnWillStart(int request_id, const GURL& url, bool* defer) { + request_id_ = request_id; + if (file_path_.empty()) { + // Defer starting the request until we have created the temporary file. + // TODO(darin): This is sub-optimal. We should not delay starting the + // network request like this. + *defer = true; + FileSystemProxy::CreateTemporary( + callback_factory_.NewCallback( + &RedirectToFileResourceHandler::DidCreateTemporaryFile)); + return true; + } return next_handler_->OnWillStart(request_id, url, defer); } @@ -103,18 +118,9 @@ bool RedirectToFileResourceHandler::OnReadCompleted(int request_id, DCHECK(new_offset <= buf_->capacity()); buf_->set_offset(new_offset); - if (!file_stream_.IsOpen()) { - int rv = file_stream_.Open(file_path_, base::PLATFORM_FILE_OPEN | - base::PLATFORM_FILE_WRITE | - base::PLATFORM_FILE_ASYNC); - if (rv != net::OK) - return false; - } - if (BufIsFull()) host_->PauseRequest(process_id_, request_id, true); - request_id_ = request_id; return WriteMore(); } @@ -127,9 +133,30 @@ bool RedirectToFileResourceHandler::OnResponseCompleted( void RedirectToFileResourceHandler::OnRequestClosed() { next_handler_->OnRequestClosed(); + + // The renderer no longer has a WebURLLoader open to this request, so we can + // close and unlink the file. + + // We require this explicit call to Close since file_stream_ was constructed + // directly from a PlatformFile. + file_stream_->Close(); + file_stream_.reset(); + + FileSystemProxy::Delete(file_path_, NULL); } RedirectToFileResourceHandler::~RedirectToFileResourceHandler() { + DCHECK(!file_stream_.get()); +} + +void RedirectToFileResourceHandler::DidCreateTemporaryFile( + base::PassPlatformFile file_handle, + FilePath file_path) { + file_path_ = file_path; + file_stream_.reset(new net::FileStream(file_handle.ReleaseValue(), + base::PLATFORM_FILE_WRITE | + base::PLATFORM_FILE_ASYNC)); + host_->StartDeferredRequest(process_id_, request_id_); } void RedirectToFileResourceHandler::DidWriteToFile(int result) { @@ -148,6 +175,7 @@ void RedirectToFileResourceHandler::DidWriteToFile(int result) { } bool RedirectToFileResourceHandler::WriteMore() { + DCHECK(file_stream_.get()); for (;;) { if (write_cursor_ == buf_->offset()) { // We've caught up to the network load, but it may be in the process of @@ -163,9 +191,9 @@ bool RedirectToFileResourceHandler::WriteMore() { if (write_callback_pending_) return true; DCHECK(write_cursor_ < buf_->offset()); - int rv = file_stream_.Write(buf_->StartOfBuffer() + write_cursor_, - buf_->offset() - write_cursor_, - &write_callback_); + int rv = file_stream_->Write(buf_->StartOfBuffer() + write_cursor_, + buf_->offset() - write_cursor_, + &write_callback_); if (rv == net::ERR_IO_PENDING) { write_callback_pending_ = true; return true; diff --git a/chrome/browser/renderer_host/redirect_to_file_resource_handler.h b/chrome/browser/renderer_host/redirect_to_file_resource_handler.h index f9d2b57..5dd4111 100644 --- a/chrome/browser/renderer_host/redirect_to_file_resource_handler.h +++ b/chrome/browser/renderer_host/redirect_to_file_resource_handler.h @@ -6,14 +6,18 @@ #define CHROME_BROWSER_RENDERER_HOST_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_ #include "base/file_path.h" +#include "base/platform_file.h" #include "base/ref_counted.h" +#include "base/scoped_callback_factory.h" +#include "base/scoped_ptr.h" #include "chrome/browser/renderer_host/resource_handler.h" #include "net/base/completion_callback.h" -#include "net/base/file_stream.h" +class RefCountedPlatformFile; class ResourceDispatcherHost; namespace net { +class FileStream; class GrowableIOBuffer; } @@ -42,10 +46,14 @@ class RedirectToFileResourceHandler : public ResourceHandler { private: virtual ~RedirectToFileResourceHandler(); + void DidCreateTemporaryFile(base::PassPlatformFile file_handle, + FilePath file_path); void DidWriteToFile(int result); bool WriteMore(); bool BufIsFull() const; + base::ScopedCallbackFactory<RedirectToFileResourceHandler> callback_factory_; + ResourceDispatcherHost* host_; scoped_refptr<ResourceHandler> next_handler_; int process_id_; @@ -63,7 +71,7 @@ class RedirectToFileResourceHandler : public ResourceHandler { int write_cursor_; FilePath file_path_; - net::FileStream file_stream_; + scoped_ptr<net::FileStream> file_stream_; net::CompletionCallbackImpl<RedirectToFileResourceHandler> write_callback_; bool write_callback_pending_; |