summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-30 23:05:15 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-30 23:05:15 +0000
commit21ae1f956c163bc0e3b3e239b5c027a7ac93ae7f (patch)
tree4eee3fe37f83559b1a97f75dcdef0337b68e2cf1 /chrome/browser/renderer_host
parent0436fcd542e8ce436fe9395a64cc03fa369276b1 (diff)
downloadchromium_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.cc58
-rw-r--r--chrome/browser/renderer_host/redirect_to_file_resource_handler.h12
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_;