blob: cf11165487f35db0992894a4f11b6765bbc477fb [file] [log] [blame]
// Copyright 2019 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 MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_FORWARDER_BASE_H_
#define MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_FORWARDER_BASE_H_
#include <memory>
#include <vector>
#include "base/callback.h"
#include "base/component_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/message.h"
namespace mojo {
class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) ThreadSafeForwarderBase
: public MessageReceiverWithResponder {
public:
using ForwardMessageCallback = base::RepeatingCallback<void(Message)>;
using ForwardMessageWithResponderCallback =
base::RepeatingCallback<void(Message, std::unique_ptr<MessageReceiver>)>;
ThreadSafeForwarderBase(
scoped_refptr<base::SequencedTaskRunner> task_runner,
ForwardMessageCallback forward,
ForwardMessageWithResponderCallback forward_with_responder,
const AssociatedGroup& associated_group);
~ThreadSafeForwarderBase() override;
// MessageReceiverWithResponder implementation:
bool PrefersSerializedMessages() override;
bool Accept(Message* message) override;
bool AcceptWithResponder(Message* message,
std::unique_ptr<MessageReceiver> responder) override;
private:
// Data that we need to share between the sequences involved in a sync call.
struct SyncResponseInfo
: public base::RefCountedThreadSafe<SyncResponseInfo> {
SyncResponseInfo();
Message message;
bool received = false;
base::WaitableEvent event{base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED};
private:
friend class base::RefCountedThreadSafe<SyncResponseInfo>;
~SyncResponseInfo();
};
// A MessageReceiver that signals |response| when it either accepts the
// response message, or is destructed.
class SyncResponseSignaler : public MessageReceiver {
public:
explicit SyncResponseSignaler(scoped_refptr<SyncResponseInfo> response);
~SyncResponseSignaler() override;
bool Accept(Message* message) override;
private:
scoped_refptr<SyncResponseInfo> response_;
};
// A record of the pending sync responses for canceling pending sync calls
// when the owning ThreadSafeForwarder is destructed.
struct InProgressSyncCalls
: public base::RefCountedThreadSafe<InProgressSyncCalls> {
InProgressSyncCalls();
// |lock| protects access to |pending_responses|.
base::Lock lock;
std::vector<SyncResponseInfo*> pending_responses;
private:
friend class base::RefCountedThreadSafe<InProgressSyncCalls>;
~InProgressSyncCalls();
};
class ForwardToCallingThread : public MessageReceiver {
public:
explicit ForwardToCallingThread(std::unique_ptr<MessageReceiver> responder);
~ForwardToCallingThread() override;
private:
bool Accept(Message* message) override;
static void CallAcceptAndDeleteResponder(
std::unique_ptr<MessageReceiver> responder,
Message message);
std::unique_ptr<MessageReceiver> responder_;
scoped_refptr<base::SequencedTaskRunner> caller_task_runner_;
};
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
const ForwardMessageCallback forward_;
const ForwardMessageWithResponderCallback forward_with_responder_;
AssociatedGroup associated_group_;
scoped_refptr<InProgressSyncCalls> sync_calls_;
DISALLOW_COPY_AND_ASSIGN(ThreadSafeForwarderBase);
};
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_THREAD_SAFE_FORWARDER_BASE_H_