| 97 | } |
| 98 | |
| 99 | void Async::runInMainSync(const std::function<void()>& worker) { |
| 100 | if (_stopped.load(std::memory_order_acquire)) { |
| 101 | return; |
| 102 | } |
| 103 | AssertUnless(SharedApplication.getLogicThread() == std::this_thread::get_id(), "Async runner should be invoked from logic thread"); |
| 104 | std::list<std::variant<WorkPtr, WorkDonePtr>> jobs; |
| 105 | for (auto event = _workerEvent.poll(); |
| 106 | event != nullptr; |
| 107 | event = _workerEvent.poll()) { |
| 108 | switch (Switch::hash(event->getName())) { |
| 109 | case "Work"_hash: { |
| 110 | Own<std::function<void()>> worker; |
| 111 | event->get(worker); |
| 112 | jobs.push_back(std::move(worker)); |
| 113 | break; |
| 114 | } |
| 115 | case "WorkDone"_hash: { |
| 116 | Own<WorkDone> workDone; |
| 117 | event->get(workDone); |
| 118 | jobs.push_back(std::move(workDone)); |
| 119 | break; |
| 120 | } |
| 121 | } |
| 122 | } |
| 123 | run([&]() { |
| 124 | worker(); |
| 125 | _mainThreadSemaphore.post(); |
| 126 | }); |
| 127 | if (_stopped.load(std::memory_order_acquire)) { |
| 128 | return; |
| 129 | } |
| 130 | _mainThreadSemaphore.wait(); |
| 131 | for (auto& job : jobs) { |
| 132 | if (std::holds_alternative<WorkPtr>(job)) { |
| 133 | _workerEvent.post("Work"_slice, std::move(std::get<WorkPtr>(job))); |
| 134 | } else { |
| 135 | _workerEvent.post("WorkDone"_slice, std::move(std::get<WorkDonePtr>(job))); |
| 136 | } |
| 137 | } |
| 138 | notifyWorker(); |
| 139 | } |
| 140 | |
| 141 | int Async::work(bx::Thread* thread, void* userData) { |
| 142 | DORA_UNUSED_PARAM(thread); |
no test coverage detected