From 21ae1f956c163bc0e3b3e239b5c027a7ac93ae7f Mon Sep 17 00:00:00 2001 From: "darin@chromium.org" Date: Fri, 30 Jul 2010 23:05:15 +0000 Subject: 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 --- base/base.gypi | 1 + base/platform_file.h | 38 ++++++++++++ base/scoped_callback_factory.h | 133 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 base/scoped_callback_factory.h (limited to 'base') diff --git a/base/base.gypi b/base/base.gypi index a5fdfc6..75fcf5b 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -186,6 +186,7 @@ 'safe_strerror_posix.h', 'scoped_bstr_win.cc', 'scoped_bstr_win.h', + 'scoped_callback_factory.h', 'scoped_cftyperef.h', 'scoped_comptr_win.h', 'scoped_handle.h', diff --git a/base/platform_file.h b/base/platform_file.h index 3571e24..43f8511 100644 --- a/base/platform_file.h +++ b/base/platform_file.h @@ -54,6 +54,44 @@ PlatformFile CreatePlatformFile(const std::wstring& name, // Closes a file handle bool ClosePlatformFile(PlatformFile file); +// Use this class to pass ownership of a PlatformFile to a receiver that may or +// may not want to accept it. This class does not own the storage for the +// PlatformFile. +// +// EXAMPLE: +// +// void MaybeProcessFile(PassPlatformFile pass_file) { +// if (...) { +// PlatformFile file = pass_file.ReleaseValue(); +// // Now, we are responsible for closing |file|. +// } +// } +// +// void OpenAndMaybeProcessFile(const FilePath& path) { +// PlatformFile file = CreatePlatformFile(path, ...); +// MaybeProcessFile(PassPlatformFile(&file)); +// if (file != kInvalidPlatformFileValue) +// ClosePlatformFile(file); +// } +// +class PassPlatformFile { + public: + explicit PassPlatformFile(PlatformFile* value) : value_(value) { + } + + // Called to retrieve the PlatformFile stored in this object. The caller + // gains ownership of the PlatformFile and is now responsible for closing it. + // Any subsequent calls to this method will return an invalid PlatformFile. + PlatformFile ReleaseValue() { + PlatformFile temp = *value_; + *value_ = kInvalidPlatformFileValue; + return temp; + } + + private: + PlatformFile* value_; +}; + } // namespace base #endif // BASE_PLATFORM_FILE_H_ diff --git a/base/scoped_callback_factory.h b/base/scoped_callback_factory.h new file mode 100644 index 0000000..a2fc1f0 --- /dev/null +++ b/base/scoped_callback_factory.h @@ -0,0 +1,133 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ScopedCallbackFactory helps in cases where you wish to allocate a Callback +// (see base/callback.h), but need to prevent any pending callbacks from +// executing when your object gets destroyed. +// +// EXAMPLE: +// +// void GatherDataAsynchronously(Callback1::Type* callback); +// +// class MyClass { +// public: +// MyClass() : factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { +// } +// +// void Process() { +// GatherDataAsynchronously(factory_.NewCallback(&MyClass::GotData)); +// } +// +// private: +// void GotData(const Data& data) { +// ... +// } +// +// base::ScopedCallbackFactory factory_; +// }; +// +// In the above example, the Process function calls GatherDataAsynchronously to +// kick off some asynchronous processing that upon completion will notify a +// callback. If in the meantime, the MyClass instance is destroyed, when the +// callback runs, it will notice that the MyClass instance is dead, and it will +// avoid calling the GotData method. + +#ifndef BASE_SCOPED_CALLBACK_FACTORY_H_ +#define BASE_SCOPED_CALLBACK_FACTORY_H_ + +#include "base/callback.h" +#include "base/weak_ptr.h" + +namespace base { + +template +class ScopedCallbackFactory { + public: + explicit ScopedCallbackFactory(T* obj) : weak_factory_(obj) { + } + + typename Callback0::Type* NewCallback( + void (T::*method)()) { + return new CallbackImpl( + weak_factory_.GetWeakPtr(), method); + } + + template + typename Callback1::Type* NewCallback( + void (T::*method)(Arg1)) { + return new CallbackImpl >( + weak_factory_.GetWeakPtr(), method); + } + + template + typename Callback2::Type* NewCallback( + void (T::*method)(Arg1, Arg2)) { + return new CallbackImpl >( + weak_factory_.GetWeakPtr(), method); + } + + template + typename Callback3::Type* NewCallback( + void (T::*method)(Arg1, Arg2, Arg3)) { + return new CallbackImpl >( + weak_factory_.GetWeakPtr(), method); + } + + template + typename Callback4::Type* NewCallback( + void (T::*method)(Arg1, Arg2, Arg3, Arg4)) { + return new CallbackImpl >( + weak_factory_.GetWeakPtr(), method); + } + + template + typename Callback5::Type* NewCallback( + void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { + return new CallbackImpl >( + weak_factory_.GetWeakPtr(), method); + } + + void RevokeAll() { weak_factory_.InvalidateWeakPtrs(); } + bool HasPendingCallbacks() const { return weak_factory_.HasWeakPtrs(); } + + private: + template + class CallbackStorage { + public: + CallbackStorage(const WeakPtr& obj, Method meth) + : obj_(obj), + meth_(meth) { + } + + protected: + WeakPtr obj_; + Method meth_; + }; + + template + class CallbackImpl : public CallbackStorage, + public CallbackRunner { + public: + CallbackImpl(const WeakPtr& obj, Method meth) + : CallbackStorage(obj, meth) { + } + virtual void RunWithParams(const Params& params) { + // Use "this->" to force C++ to look inside our templatized base class; + // see Effective C++, 3rd Ed, item 43, p210 for details. + if (!this->obj_) + return; + DispatchToMethod(this->obj_.get(), this->meth_, params); + } + }; + + WeakPtrFactory weak_factory_; +}; + +} // namespace base + +#endif // BASE_SCOPED_CALLBACK_FACTORY_H_ -- cgit v1.1