#include #include #include #include #include #include namespace mbgl { namespace util { class RunLoop::Impl { public: std::unique_ptr async; }; RunLoop* RunLoop::Get() { assert(static_cast(Scheduler::GetCurrent())); return static_cast(Scheduler::GetCurrent()); } RunLoop::RunLoop(Type) : impl(std::make_unique()) { assert(!Scheduler::GetCurrent()); Scheduler::SetCurrent(this); impl->async = std::make_unique(std::bind(&RunLoop::process, this)); } RunLoop::~RunLoop() { Scheduler::SetCurrent(nullptr); } void RunLoop::wake() { impl->async->send(); } void RunLoop::run() { CFRunLoopRun(); } void RunLoop::runOnce() { wake(); CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); } void RunLoop::stop() { invoke([&] { CFRunLoopStop(CFRunLoopGetCurrent()); }); } std::size_t RunLoop::waitForEmpty(Milliseconds timeout) { const auto startTime = mbgl::util::MonotonicTimer::now(); while (true) { std::size_t remaining; { std::lock_guard lock(mutex); remaining = defaultQueue.size() + highPriorityQueue.size(); } const auto elapsed = mbgl::util::MonotonicTimer::now() - startTime; const auto elapsedMillis = std::chrono::duration_cast(elapsed); if (remaining == 0 || (Milliseconds::zero() < timeout && timeout <= elapsedMillis)) { return remaining; } runOnce(); } } } // namespace util } // namespace mbgl