From baa64a1461bbfafd947d338e90d9202987150271 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 8 May 2020 09:19:57 +0800 Subject: [PATCH] fix animation deadlock issues(#530) --- source/gui/animation.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/source/gui/animation.cpp b/source/gui/animation.cpp index f897735f..ce213ee2 100644 --- a/source/gui/animation.cpp +++ b/source/gui/animation.cpp @@ -1,7 +1,7 @@ /* * An Animation Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2020 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -429,6 +429,14 @@ namespace nana if(state.this_frameset != framesets.end()) state.this_frameset->impl_->reset(); } + + bool eof() const + { + if(state.this_frameset != framesets.end()) + return state.this_frameset->impl_->eof(); + + return true; + } };//end struct animation::impl //class animation::performance_manager @@ -463,6 +471,9 @@ namespace nana tmpiece.start(); { + //acquire the isg lock first to avoid deadlock that occured by an event hander which operates the animation object. + nana::internal_scope_guard isglock; + std::lock_guardmutex)> lock(thr->mutex); for (auto ani : thr->animations) { @@ -525,10 +536,13 @@ namespace nana return; } - std::lock_guardmutex)> privlock(thr->mutex); - auto u = std::find(thr->animations.begin(), thr->animations.end(), p); - if (u != thr->animations.end()) - thr->animations.erase(u); + { + // the mutex of thread variable may be acquired by insert() + std::lock_guardmutex)> privlock(thr->mutex); + auto u = std::find(thr->animations.begin(), thr->animations.end(), p); + if (u != thr->animations.end()) + thr->animations.erase(u); + } p->thr_variable = nullptr; insert(p); @@ -633,6 +647,9 @@ namespace nana std::unique_lock lock(impl_->thr_variable->mutex); if(0 == impl_->thr_variable->active) { + if (impl_->eof()) + impl_->reset(); + impl_->thr_variable->active = 1; impl_->thr_variable->condvar.notify_one(); }