[core] Abstract main loop inside RunLoop class
This commit is contained in:
83
platform/default/run_loop.cpp
Normal file
83
platform/default/run_loop.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
uv::tls<RunLoop> RunLoop::current;
|
||||
|
||||
class RunLoop::Impl {
|
||||
public:
|
||||
Impl() = default;
|
||||
|
||||
uv_loop_t *loop;
|
||||
RunLoop::Type type;
|
||||
};
|
||||
|
||||
RunLoop::RunLoop(Type type) : impl(std::make_unique<Impl>()) {
|
||||
switch (type) {
|
||||
case Type::New:
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
impl->loop = uv_loop_new();
|
||||
if (impl->loop == nullptr) {
|
||||
#else
|
||||
impl->loop = new uv_loop_t;
|
||||
if (uv_loop_init(impl->loop) != 0) {
|
||||
#endif
|
||||
throw std::runtime_error("Failed to initialize loop.");
|
||||
}
|
||||
break;
|
||||
case Type::Default:
|
||||
impl->loop = uv_default_loop();
|
||||
break;
|
||||
}
|
||||
|
||||
impl->type = type;
|
||||
|
||||
current.set(this);
|
||||
async = std::make_unique<AsyncTask>(std::bind(&RunLoop::process, this));
|
||||
}
|
||||
|
||||
RunLoop::~RunLoop() {
|
||||
current.set(nullptr);
|
||||
|
||||
if (impl->type == Type::Default) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the loop again to ensure that async
|
||||
// close callbacks have been called. Not needed
|
||||
// for the default main loop because it is only
|
||||
// closed when the application exits.
|
||||
async.reset();
|
||||
runOnce();
|
||||
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
uv_loop_delete(impl->loop);
|
||||
#else
|
||||
if (uv_loop_close(impl->loop) == UV_EBUSY) {
|
||||
throw std::runtime_error("Failed to close loop.");
|
||||
}
|
||||
delete impl->loop;
|
||||
#endif
|
||||
}
|
||||
|
||||
LOOP_HANDLE RunLoop::getLoopHandle() {
|
||||
return current.get()->impl->loop;
|
||||
}
|
||||
|
||||
void RunLoop::run() {
|
||||
uv_run(impl->loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
void RunLoop::runOnce() {
|
||||
uv_run(impl->loop, UV_RUN_ONCE);
|
||||
}
|
||||
|
||||
void RunLoop::stop() {
|
||||
invoke([&] { async->unref(); });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user