Index: media/base/callback_wrapper.h |
diff --git a/media/base/callback_wrapper.h b/media/base/callback_wrapper.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..02ced86769bbe07313cede2388c4a5504079cce4 |
--- /dev/null |
+++ b/media/base/callback_wrapper.h |
@@ -0,0 +1,71 @@ |
+// Copyright (c) 2012 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. |
+ |
+#ifndef MEDIA_BASE_CALLBACK_WRAPPER_H_ |
+#define MEDIA_BASE_CALLBACK_WRAPPER_H_ |
+ |
+#include "base/callback.h" |
+#include "base/message_loop_proxy.h" |
+ |
+// This is a helper utility for running callbacks on the current message loop as |
+// a freshly posted task as opposed to executing on the current stack. |
+// |
+// Typical usage is when implementing an asynchronous callback-accepting |
+// interface in a synchronous fashion. Running the callback as a posted task |
+// prevents reentrancy into the calling code. |
+// |
+// void MyClass::DoSomethingAsync(const base::Closure& closure) { |
+// DoWorkSynchronously(); |
+// WrapCB(closure).Run(); |
+// } |
+ |
+namespace media { |
+ |
+namespace internal { |
+void RunWrappedCB( |
scherkus (not reviewing)
2012/12/06 21:57:57
I just realized I was completely mistaken about Bi
|
+ const scoped_refptr<base::MessageLoopProxy>& message_loop, |
+ const base::Closure& cb) { |
+ message_loop->PostTask(FROM_HERE, cb); |
+} |
+ |
+template<typename A1> |
+void RunWrappedCBWithArgs( |
+ const scoped_refptr<base::MessageLoopProxy>& message_loop, |
+ const base::Callback<void(A1)>& cb, |
+ A1 a1) { |
+ RunWrappedCB(message_loop, base::Bind(cb, a1)); |
+} |
+ |
+template<typename A1, typename A2> |
+void RunWrappedCBWithArgs( |
+ const scoped_refptr<base::MessageLoopProxy>& message_loop, |
+ const base::Callback<void(A1, A2)>& cb, |
+ A1 a1, A2 a2) { |
+ RunWrappedCB(message_loop, base::Bind(cb, a1, a2)); |
+} |
+} // namespace internal |
+ |
+base::Closure WrapCB(const base::Closure& cb) { |
+ return base::Bind( |
+ &internal::RunWrappedCB, |
+ base::MessageLoopProxy::current(), cb); |
+} |
+ |
+template<typename A1> |
+base::Callback<void(A1)> WrapCB(const base::Callback<void(A1)>& cb) { |
+ return base::Bind( |
+ &internal::RunWrappedCBWithArgs<A1>, |
+ base::MessageLoopProxy::current(), cb); |
+} |
+ |
+template<typename A1, typename A2> |
+base::Callback<void(A1, A2)> WrapCB(const base::Callback<void(A1, A2)>& cb) { |
+ return base::Bind( |
+ &internal::RunWrappedCBWithArgs<A1, A2>, |
+ base::MessageLoopProxy::current(), cb); |
+} |
+ |
+} // namespace media |
+ |
+#endif // MEDIA_BASE_CALLBACK_WRAPPER_H_ |