rtc::Thread::PostTask() added.

This method allows asynchronously posting tasks, in the form of
functors to be invoked, on the thread represented by rtc::Thread.

This CL removes PostMessageWithFunctor(), putting the implementation of
it directly into rtc::Thread::PostTask(), and moves & updates the test
coverage to thread_unittest.cc.

Bug: webrtc:10294, webrtc:10293
Change-Id: Ic6cc3e2533a4f7aaff141aff28e9bb3908ee3c96
Reviewed-on: https://webrtc-review.googlesource.com/c/124701
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26894}
diff --git a/rtc_base/thread.h b/rtc_base/thread.h
index 3ba3010..7bb7a3c 100644
--- a/rtc_base/thread.h
+++ b/rtc_base/thread.h
@@ -36,6 +36,29 @@
 
 class Thread;
 
+namespace rtc_thread_internal {
+
+template <class FunctorT>
+class SingleMessageHandlerWithFunctor final : public MessageHandler {
+ public:
+  explicit SingleMessageHandlerWithFunctor(FunctorT&& functor)
+      : functor_(std::forward<FunctorT>(functor)) {}
+
+  void OnMessage(Message* msg) override {
+    functor_();
+    delete this;
+  }
+
+ private:
+  ~SingleMessageHandlerWithFunctor() override {}
+
+  typename std::remove_reference<FunctorT>::type functor_;
+
+  RTC_DISALLOW_COPY_AND_ASSIGN(SingleMessageHandlerWithFunctor);
+};
+
+}  // namespace rtc_thread_internal
+
 class ThreadManager {
  public:
   static const int kForever = -1;
@@ -183,6 +206,8 @@
   // &MyFunctionReturningBool);
   // NOTE: This function can only be called when synchronous calls are allowed.
   // See ScopedDisallowBlockingCalls for details.
+  // NOTE: Blocking invokes are DISCOURAGED, consider if what you're doing can
+  // be achieved with PostTask() and callbacks instead.
   template <class ReturnT, class FunctorT>
   ReturnT Invoke(const Location& posted_from, FunctorT&& functor) {
     FunctorMessageHandler<ReturnT, FunctorT> handler(
@@ -191,6 +216,44 @@
     return handler.MoveResult();
   }
 
+  // Posts a task to invoke the functor on |this| thread asynchronously, i.e.
+  // without blocking the thread that invoked PostTask(). Ownership of |functor|
+  // is passed and destroyed on |this| thread after it is invoked.
+  // Requirements of FunctorT:
+  // - FunctorT is movable.
+  // - FunctorT implements "T operator()()" or "T operator()() const" for some T
+  //   (if T is not void, the return value is discarded on |this| thread).
+  // - FunctorT has a public destructor that can be invoked from |this| thread
+  //   after operation() has been invoked.
+  // - The functor must not cause the thread to quit before PostTask() is done.
+  //
+  // Example - Calling a class method:
+  // class Foo {
+  //  public:
+  //   void DoTheThing();
+  // };
+  // Foo foo;
+  // thread->PostTask(RTC_FROM_HERE, Bind(&Foo::DoTheThing, &foo));
+  //
+  // Example - Calling a lambda function:
+  // thread->PostTask(RTC_FROM_HERE,
+  //                  [&x, &y] { x.TrackComputations(y.Compute()); });
+  template <class FunctorT>
+  void PostTask(const Location& posted_from, FunctorT&& functor) {
+    Post(posted_from,
+         new rtc_thread_internal::SingleMessageHandlerWithFunctor<FunctorT>(
+             std::forward<FunctorT>(functor)));
+    // This DCHECK guarantees that the post was successful.
+    // Post() doesn't say whether it succeeded, but it will only fail if the
+    // thread is quitting. DCHECKing that the thread is not quitting *after*
+    // posting might yield some false positives (where the thread did in fact
+    // quit, but only after posting), but if we have false positives here then
+    // we have a race condition anyway.
+    // TODO(https://crbug.com/webrtc/10364): When Post() returns a bool we can
+    // DCHECK the result instead of inferring success from IsQuitting().
+    RTC_DCHECK(!IsQuitting());
+  }
+
   // From MessageQueue
   bool IsProcessingMessagesForTesting() override;
   void Clear(MessageHandler* phandler,