/* * Copyright 2019 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef RTC_BASE_POST_MESSAGE_WITH_FUNCTOR_H_ #define RTC_BASE_POST_MESSAGE_WITH_FUNCTOR_H_ #include #include "rtc_base/checks.h" #include "rtc_base/constructor_magic.h" #include "rtc_base/location.h" #include "rtc_base/message_handler.h" #include "rtc_base/thread.h" namespace rtc { namespace post_message_with_functor_internal { template class SingleMessageHandlerWithFunctor : public MessageHandler { public: template explicit SingleMessageHandlerWithFunctor(F&& functor) : functor_(std::forward(functor)) {} void OnMessage(Message* msg) override { functor_(); delete this; } private: ~SingleMessageHandlerWithFunctor() override {} typename std::remove_reference::type functor_; RTC_DISALLOW_COPY_AND_ASSIGN(SingleMessageHandlerWithFunctor); }; } // namespace post_message_with_functor_internal // Asynchronously posts a message that will invoke |functor| on the target // thread. Ownership is passed and |functor| is destroyed on the target thread. // 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 the target thread). // - FunctorT has a public destructor that can be invoked from the target // thread after operation() has been invoked. // - The functor must not cause the thread to quit before // PostMessageWithFunctor() is done. template void PostMessageWithFunctor(const Location& posted_from, Thread* thread, FunctorT&& functor) { thread->Post( posted_from, new post_message_with_functor_internal::SingleMessageHandlerWithFunctor< FunctorT>(std::forward(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. RTC_DCHECK(!thread->IsQuitting()); } } // namespace rtc #endif // RTC_BASE_POST_MESSAGE_WITH_FUNCTOR_H_