Wait for pause

Tidy up
Remove red fill
This commit is contained in:
Leith Bade
2014-11-09 23:52:34 +11:00
parent 3696e05193
commit 1e55c332cd
4 changed files with 47 additions and 65 deletions

View File

@@ -316,7 +316,7 @@ bool NativeMapView::createSurface(ANativeWindow* window_) {
void NativeMapView::destroySurface() {
LOG_VERBOSE("NativeMapView::destroySurface");
pause();
pause(true);
if (surface != EGL_NO_SURFACE) {
if (!eglDestroySurface(display, surface)) {
@@ -518,13 +518,13 @@ void NativeMapView::stop() {
}
void NativeMapView::pause() {
LOG_VERBOSE("NativeMapView::pause");
void NativeMapView::pause(bool wait_for_pause) {
LOG_VERBOSE("NativeMapView::pause %s", (wait_for_pause) ? "true" : "false");
LOG_ASSERT(display != EGL_NO_DISPLAY);
LOG_ASSERT(context != EGL_NO_CONTEXT);
map->pause();
map->pause(wait_for_pause);
}
void NativeMapView::resume() {

View File

@@ -63,7 +63,7 @@ public:
void stop();
void resume();
void pause();
void pause(bool wait_for_pause = false);
void notifyMapChange();

View File

@@ -178,9 +178,12 @@ private:
private:
bool terminating = false;
bool pausing = false;
bool is_paused = false;
std::unique_ptr<uv::mutex> mutex_run;
std::unique_ptr<uv::cond> cond_run;
std::unique_ptr<uv::mutex> mutex_pause;
std::unique_ptr<uv::cond> cond_resume;
std::unique_ptr<uv::cond> cond_pause;
private:
// If cleared, the next time the render thread attempts to render the map, it will *actually*

View File

@@ -36,8 +36,10 @@ Map::Map(View& view_)
async_terminate(new uv_async_t()),
async_render(new uv_async_t()),
async_cleanup(new uv_async_t()),
mutex_run(std::make_unique<uv::mutex>()),
cond_run(std::make_unique<uv::cond>()),
mutex_pause(std::make_unique<uv::mutex>()),
cond_resume(std::make_unique<uv::cond>()),
cond_pause(std::make_unique<uv::cond>()),
view(view_),
#ifndef NDEBUG
main_thread(uv_thread_self()),
@@ -89,11 +91,6 @@ void Map::start(bool start_paused) {
// Reset the flag.
is_stopped = false;
// Do we need to pause first?
if (start_paused) {
pause();
}
// Setup async notifications
// Iron out the differences between libuv 0.10 and 0.11
@@ -117,6 +114,11 @@ void Map::start(bool start_paused) {
#undef UV_ASYNC_CALLBACK
// Do we need to pause first?
if (start_paused) {
pause();
}
uv_thread_create(*thread, [](void *arg) {
Map *map = static_cast<Map *>(arg);
#ifndef NDEBUG
@@ -167,42 +169,30 @@ void Map::stop(stop_callback cb, void *data) {
void Map::pause(bool wait_for_pause) {
assert(uv_thread_self() == main_thread);
assert(async);
Log::Info(Event::General, "Map::pause() start");
mutex_run->lock();
pausing = true;
mutex_run->unlock();
// TODO wait until paused before return
Log::Info(Event::General, "Map::pause() locking");
mutex_pause->lock();
Log::Info(Event::General, "Map::pause() locked");
is_paused = true;
Log::Info(Event::General, "Map::pause() set is_paused = true");
Log::Info(Event::General, "Map::pause() unlocking");
mutex_pause->unlock();
Log::Info(Event::General, "Map::pause() unlocked");
Log::Info(Event::General, "Map::pause() stopping loop");
uv_stop(**loop);
Log::Info(Event::General, "Map::pause() stopping done");
rerender(); // Needed to ensure uv_stop is seen and uv_run exits, otherwise we deadlock on wait_for_pause
if (wait_for_pause) {
mutex_pause->lock();
while (!is_paused) {
cond_pause->wait(*mutex_pause);
}
mutex_pause->unlock();
}
}
void Map::resume() {
assert(uv_thread_self() == main_thread);
assert(async);
Log::Info(Event::General, "Map::resume() start");
Log::Info(Event::General, "Map::resume() locking");
mutex_pause->lock();
Log::Info(Event::General, "Map::resume() locked");
is_paused = false;
Log::Info(Event::General, "Map::resume() set is_paused = false");
Log::Info(Event::General, "Map::resume() broadcasting");
cond_resume->broadcast();
Log::Info(Event::General, "Map::resume() broadcasted");
Log::Info(Event::General, "Map::resume() unlocking");
mutex_pause->unlock();
Log::Info(Event::General, "Map::resume() unlocked");
Log::Info(Event::General, "Map::resume() done");
mutex_run->lock();
pausing = false;
cond_run->broadcast();
mutex_run->unlock();
}
void Map::run() {
@@ -218,24 +208,12 @@ void Map::run() {
setup();
prepare();
Log::Info(Event::General, "Map::run() start");
terminating = false;
Log::Info(Event::General, "Map::run() set terminating = false");
Log::Info(Event::General, "Map::run() entering run loop");
while(!terminating) {
Log::Info(Event::General, "Map::run() next run loop, terminating = %s", terminating ? "true" : "false");
Log::Info(Event::General, "Map::run() uv_run enter");
uv_run(**loop, UV_RUN_DEFAULT);
Log::Info(Event::General, "Map::run() exit");
check_for_pause();
//uv_run(**loop, UV_RUN_DEFAULT);
}
Log::Info(Event::General, "Map::run() run loop exit");
// Run the event loop once more to make sure our async delete handlers are called.
uv_run(**loop, UV_RUN_ONCE);
@@ -250,20 +228,21 @@ void Map::run() {
}
void Map::check_for_pause() {
Log::Info(Event::General, "Map::check_for_pause() locking");
mutex_pause->lock();
Log::Info(Event::General, "Map::check_for_pause() locked");
Log::Info(Event::General, "Map::check_for_pause() entering pause loop");
while (is_paused) {
Log::Info(Event::General, "Map::check_for_pause() next pause loop, is_paused = %s", is_paused ? "true" : "false");
Log::Info(Event::General, "Map::check_for_pause() waiting");
cond_resume->wait(*mutex_pause);
Log::Info(Event::General, "Map::check_for_pause() waited");
mutex_run->lock();
while (pausing) {
mutex_pause->lock();
is_paused = true;
cond_pause->broadcast();
mutex_pause->unlock();
cond_run->wait(*mutex_run);
}
Log::Info(Event::General, "Map::check_for_pause() exit pause loop");
Log::Info(Event::General, "Map::check_for_pause() unlocking");
mutex_pause->lock();
is_paused = false;
mutex_pause->unlock();
Log::Info(Event::General, "Map::check_for_pause() unlocked");
mutex_run->unlock();
}
void Map::rerender() {