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 /base | |
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 'base')
-rw-r--r-- | base/base.gypi | 1 | ||||
-rw-r--r-- | base/platform_file.h | 38 | ||||
-rw-r--r-- | base/scoped_callback_factory.h | 133 |
3 files changed, 172 insertions, 0 deletions
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<Data>::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<MyClass> 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 T> +class ScopedCallbackFactory { + public: + explicit ScopedCallbackFactory(T* obj) : weak_factory_(obj) { + } + + typename Callback0::Type* NewCallback( + void (T::*method)()) { + return new CallbackImpl<void (T::*)(), Tuple0 >( + weak_factory_.GetWeakPtr(), method); + } + + template <typename Arg1> + typename Callback1<Arg1>::Type* NewCallback( + void (T::*method)(Arg1)) { + return new CallbackImpl<void (T::*)(Arg1), Tuple1<Arg1> >( + weak_factory_.GetWeakPtr(), method); + } + + template <typename Arg1, typename Arg2> + typename Callback2<Arg1, Arg2>::Type* NewCallback( + void (T::*method)(Arg1, Arg2)) { + return new CallbackImpl<void (T::*)(Arg1, Arg2), Tuple2<Arg1, Arg2> >( + weak_factory_.GetWeakPtr(), method); + } + + template <typename Arg1, typename Arg2, typename Arg3> + typename Callback3<Arg1, Arg2, Arg3>::Type* NewCallback( + void (T::*method)(Arg1, Arg2, Arg3)) { + return new CallbackImpl<void (T::*)(Arg1, Arg2, Arg3), + Tuple3<Arg1, Arg2, Arg3> >( + weak_factory_.GetWeakPtr(), method); + } + + template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> + typename Callback4<Arg1, Arg2, Arg3, Arg4>::Type* NewCallback( + void (T::*method)(Arg1, Arg2, Arg3, Arg4)) { + return new CallbackImpl<void (T::*)(Arg1, Arg2, Arg3, Arg4), + Tuple4<Arg1, Arg2, Arg3, Arg4> >( + weak_factory_.GetWeakPtr(), method); + } + + template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, + typename Arg5> + typename Callback5<Arg1, Arg2, Arg3, Arg4, Arg5>::Type* NewCallback( + void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { + return new CallbackImpl<void (T::*)(Arg1, Arg2, Arg3, Arg4, Arg5), + Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> >( + weak_factory_.GetWeakPtr(), method); + } + + void RevokeAll() { weak_factory_.InvalidateWeakPtrs(); } + bool HasPendingCallbacks() const { return weak_factory_.HasWeakPtrs(); } + + private: + template <typename Method> + class CallbackStorage { + public: + CallbackStorage(const WeakPtr<T>& obj, Method meth) + : obj_(obj), + meth_(meth) { + } + + protected: + WeakPtr<T> obj_; + Method meth_; + }; + + template <typename Method, typename Params> + class CallbackImpl : public CallbackStorage<Method>, + public CallbackRunner<Params> { + public: + CallbackImpl(const WeakPtr<T>& obj, Method meth) + : CallbackStorage<Method>(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<T> weak_factory_; +}; + +} // namespace base + +#endif // BASE_SCOPED_CALLBACK_FACTORY_H_ |