#include "base/logging.h"
#include "base/message_loop/message_pump.h"
#include "base/run_loop.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
static scoped_refptr<base::SingleThreadTaskRunner> g_main_thread_task_runner;
static scoped_refptr<base::SingleThreadTaskRunner> g_io_thread_task_runner;
void RunOnIOThread();
void RunOnUIThread() {
LOG(INFO) << "RunOnUIThread()";
g_io_thread_task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RunOnIOThread), base::Seconds(1));
}
void RunOnIOThread() {
LOG(INFO) << "RunOnIOThread()";
g_main_thread_task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RunOnUIThread), base::Seconds(1));
}
class IOThreadDelegate : public base::Thread::Delegate {
public:
IOThreadDelegate() {
owned_sequence_manager_ =
base::sequence_manager::CreateUnboundSequenceManager();
task_queue_ = owned_sequence_manager_->CreateTaskQueue(
base::sequence_manager::TaskQueue::Spec(
base::sequence_manager::TaskQueue::Spec(
base::sequence_manager::QueueName::IO_DEFAULT_TQ)));
default_task_runner_ = task_queue_->task_runner();
owned_sequence_manager_->SetDefaultTaskRunner(default_task_runner_);
g_io_thread_task_runner = default_task_runner_;
}
void BindToCurrentThread() override {
owned_sequence_manager_->BindToMessagePump(
base::MessagePump::Create(base::MessagePumpType::IO));
owned_sequence_manager_->SetDefaultTaskRunner(GetDefaultTaskRunner());
}
scoped_refptr<base::SingleThreadTaskRunner> GetDefaultTaskRunner() override {
return default_task_runner_;
}
void AddTaskObserver(base::TaskObserver* observer) override {
owned_sequence_manager_->AddTaskObserver(observer);
}
private:
std::unique_ptr<base::sequence_manager::SequenceManager>
owned_sequence_manager_;
base::sequence_manager::TaskQueue::Handle task_queue_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
};
int main() {
base::PlatformThread::SetName("SchedulingDemoMain");
std::unique_ptr<base::MessagePump> pump =
base::MessagePump::Create(base::MessagePumpType::UI);
std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager =
base::sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
std::move(pump));
base::sequence_manager::TaskQueue::Handle main_task_queue =
sequence_manager->CreateTaskQueue(base::sequence_manager::TaskQueue::Spec(
base::sequence_manager::TaskQueue::Spec(
base::sequence_manager::QueueName::DEFAULT_TQ)));
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner =
main_task_queue->task_runner();
sequence_manager->SetDefaultTaskRunner(default_task_runner);
g_main_thread_task_runner = default_task_runner;
std::unique_ptr<IOThreadDelegate> delegate =
std::make_unique<IOThreadDelegate>();
base::Thread io_thread("IOThread");
base::Thread::Options options;
options.delegate = std::move(delegate);
if (!io_thread.StartWithOptions(std::move(options))) {
LOG(FATAL) << "The thread failed to start!";
}
base::RunLoop run_loop;
g_main_thread_task_runner->PostTask(FROM_HERE,
base::BindOnce(&RunOnUIThread));
g_main_thread_task_runner->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
base::Seconds(10));
run_loop.Run();
return 0;
}