1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
---|---|
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #include "flutter/fml/message_loop.h" |
6 | |
7 | #include <utility> |
8 | |
9 | #include "flutter/fml/memory/ref_counted.h" |
10 | #include "flutter/fml/memory/ref_ptr.h" |
11 | #include "flutter/fml/message_loop_impl.h" |
12 | #include "flutter/fml/task_runner.h" |
13 | #include "flutter/fml/thread_local.h" |
14 | |
15 | namespace fml { |
16 | |
17 | FML_THREAD_LOCAL ThreadLocalUniquePtr<MessageLoop> tls_message_loop; |
18 | |
19 | MessageLoop& MessageLoop::GetCurrent() { |
20 | auto* loop = tls_message_loop.get(); |
21 | FML_CHECK(loop != nullptr) |
22 | << "MessageLoop::EnsureInitializedForCurrentThread was not called on " |
23 | "this thread prior to message loop use."; |
24 | return *loop; |
25 | } |
26 | |
27 | void MessageLoop::EnsureInitializedForCurrentThread() { |
28 | if (tls_message_loop.get() != nullptr) { |
29 | // Already initialized. |
30 | return; |
31 | } |
32 | tls_message_loop.reset(new MessageLoop()); |
33 | } |
34 | |
35 | bool MessageLoop::IsInitializedForCurrentThread() { |
36 | return tls_message_loop.get() != nullptr; |
37 | } |
38 | |
39 | MessageLoop::MessageLoop() |
40 | : loop_(MessageLoopImpl::Create()), |
41 | task_runner_(fml::MakeRefCounted<fml::TaskRunner>(loop_)) { |
42 | FML_CHECK(loop_); |
43 | FML_CHECK(task_runner_); |
44 | } |
45 | |
46 | MessageLoop::~MessageLoop() = default; |
47 | |
48 | void MessageLoop::Run() { |
49 | loop_->DoRun(); |
50 | } |
51 | |
52 | void MessageLoop::Terminate() { |
53 | loop_->DoTerminate(); |
54 | } |
55 | |
56 | fml::RefPtr<fml::TaskRunner> MessageLoop::GetTaskRunner() const { |
57 | return task_runner_; |
58 | } |
59 | |
60 | fml::RefPtr<MessageLoopImpl> MessageLoop::GetLoopImpl() const { |
61 | return loop_; |
62 | } |
63 | |
64 | void MessageLoop::AddTaskObserver(intptr_t key, const fml::closure& callback) { |
65 | loop_->AddTaskObserver(key, callback); |
66 | } |
67 | |
68 | void MessageLoop::RemoveTaskObserver(intptr_t key) { |
69 | loop_->RemoveTaskObserver(key); |
70 | } |
71 | |
72 | void MessageLoop::RunExpiredTasksNow() { |
73 | loop_->RunExpiredTasksNow(); |
74 | } |
75 | |
76 | TaskQueueId MessageLoop::GetCurrentTaskQueueId() { |
77 | auto* loop = tls_message_loop.get(); |
78 | FML_CHECK(loop != nullptr) |
79 | << "MessageLoop::EnsureInitializedForCurrentThread was not called on " |
80 | "this thread prior to message loop use."; |
81 | return loop->GetLoopImpl()->GetTaskQueueId(); |
82 | } |
83 | |
84 | } // namespace fml |
85 |