blob: 389724d594d9134554900c3435568d072ac17eb8 [file] [log] [blame]
/*
* 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 <utility>
#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 FunctorT>
class SingleMessageHandlerWithFunctor : public MessageHandler {
public:
template <class F>
explicit SingleMessageHandlerWithFunctor(F&& functor)
: functor_(std::forward<F>(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 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 <class FunctorT>
void PostMessageWithFunctor(const Location& posted_from,
Thread* thread,
FunctorT&& functor) {
thread->Post(
posted_from,
new post_message_with_functor_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.
RTC_DCHECK(!thread->IsQuitting());
}
} // namespace rtc
#endif // RTC_BASE_POST_MESSAGE_WITH_FUNCTOR_H_