From 5acbbf548eff27de12c30e96e828c7bd0322cc28 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 10 Jul 2019 04:25:00 +0800 Subject: [PATCH] refactoring and fix fix a potential dead-lock caused by timer --- include/nana/gui.hpp | 55 ++++++++++++++++- include/nana/gui/compact.hpp | 57 +++++++++++++++++ include/nana/gui/wvl.hpp | 88 --------------------------- source/gui/detail/bedrock_pi.cpp | 3 +- source/gui/detail/bedrock_windows.cpp | 3 +- source/gui/msgbox.cpp | 4 +- source/gui/timer.cpp | 25 +++----- source/gui/widgets/categorize.cpp | 4 +- source/gui/widgets/combox.cpp | 4 +- source/gui/widgets/listbox.cpp | 2 +- source/gui/widgets/menu.cpp | 3 +- source/gui/wvl.cpp | 5 +- source/unicode_bidi.cpp | 14 +++++ 13 files changed, 152 insertions(+), 115 deletions(-) create mode 100644 include/nana/gui/compact.hpp delete mode 100644 include/nana/gui/wvl.hpp diff --git a/include/nana/gui.hpp b/include/nana/gui.hpp index 70bcb077..09c2f7b9 100644 --- a/include/nana/gui.hpp +++ b/include/nana/gui.hpp @@ -1 +1,54 @@ -#include "gui/wvl.hpp" \ No newline at end of file +/** + * Nana GUI Header + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file nana/gui.hpp + * @description + * the header file contains the files required for running of Nana.GUI + */ + +#ifndef NANA_GUI_HPP +#define NANA_GUI_HPP + +#include "gui/compact.hpp" +#include "gui/screen.hpp" +#include "gui/widgets/form.hpp" +#include "gui/drawing.hpp" +#include "gui/msgbox.hpp" +#include "gui/place.hpp" + + +namespace nana +{ +#ifdef NANA_AUTOMATIC_GUI_TESTING + + /// @brief Take control of the GUI and optionally automatically tests it. + /// + /// @detail It transfers to nana the program flow control, which begin pumping messages + /// from the underlying OS, interpreting and sending it with suitable arguments + /// to the nana widgets that registered a response in the corresponding event. + /// It also accept arguments to be used in case of automatic GUI testing. + /// Other Way the arguments are ignored. + void exec( + unsigned wait = 1, ///< for the GUI to be constructed, in seconds + unsigned wait_end = 1, ///< for the GUI to be destructed, in seconds + std::function = {} ///< emit events to mimics user actions and may assert results + ); + + /// send a click message to this widget - useful in GUI testing + void click(widget& w); + + /// in seconds + void Wait(unsigned wait = 0); +#else + void exec(); +#endif + + +}//end namespace nana +#endif diff --git a/include/nana/gui/compact.hpp b/include/nana/gui/compact.hpp new file mode 100644 index 00000000..c4a9789a --- /dev/null +++ b/include/nana/gui/compact.hpp @@ -0,0 +1,57 @@ +/** + * Nana GUI Library Definition + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file nana/gui/compact.hpp + * @description + * the header file contains the files required for running of Nana.GUI + */ + +#ifndef NANA_GUI_WVL_HPP +#define NANA_GUI_WVL_HPP + +#include "programming_interface.hpp" + +namespace nana +{ + namespace detail + { + struct form_loader_private + { + template friend class form_loader; + private: + static void insert_form(::nana::widget*); + }; + + template + class form_loader + { + public: + template + Form & operator()(Args &&... args) const + { + auto p = new Form(std::forward(args)...); + + if (p->empty()) + throw std::runtime_error("form_loader failed to create the form"); + + + detail::form_loader_private::insert_form(p); + if (IsVisible) + p->show(); + + return *p; + } + + }; + } + + template + using form_loader = detail::form_loader; +}//end namespace nana +#endif diff --git a/include/nana/gui/wvl.hpp b/include/nana/gui/wvl.hpp deleted file mode 100644 index c18be253..00000000 --- a/include/nana/gui/wvl.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Nana GUI Library Definition - * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * @file nana/gui/wvl.hpp - * @description - * the header file contains the files required for running of Nana.GUI - */ - -#ifndef NANA_GUI_WVL_HPP -#define NANA_GUI_WVL_HPP - -#include "programming_interface.hpp" -#include "screen.hpp" -#include "widgets/form.hpp" -#include "drawing.hpp" -#include "msgbox.hpp" -#include "place.hpp" - - -namespace nana -{ - namespace detail - { - struct form_loader_private - { - template friend class form_loader; - private: - static void insert_form(::nana::widget*); - }; - - template - class form_loader - { - public: - template - Form & operator()(Args &&... args) const - { - auto p = new Form(std::forward(args)...); - - if (p->empty()) - throw std::logic_error("form_loader failed to create the form"); - - detail::form_loader_private::insert_form(p); - if (IsVisible) - p->show(); - - return *p; - } - - }; - } - - template - using form_loader = detail::form_loader; - -#ifdef NANA_AUTOMATIC_GUI_TESTING - - /// @brief Take control of the GUI and optionally automatically tests it. - /// - /// @detail It transfers to nana the program flow control, which begin pumping messages - /// from the underlying OS, interpreting and sending it with suitable arguments - /// to the nana widgets that registered a response in the corresponding event. - /// It also accept arguments to be used in case of automatic GUI testing. - /// Other Way the arguments are ignored. - void exec( - unsigned wait = 1, ///< for the GUI to be constructed, in seconds - unsigned wait_end = 1, ///< for the GUI to be destructed, in seconds - std::function = {} ///< emit events to mimics user actions and may assert results - ); - - /// send a click message to this widget - useful in GUI testing - void click(widget& w); - - /// in seconds - void Wait(unsigned wait = 0); -#else - void exec(); -#endif - - -}//end namespace nana -#endif diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index bf4e387b..5f31b3d2 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -13,10 +13,11 @@ #include "../../detail/platform_spec_selector.hpp" #include "basic_window.hpp" #include "bedrock_types.hpp" +#include +#include #include #include #include -#include #include #include #include diff --git a/source/gui/detail/bedrock_windows.cpp b/source/gui/detail/bedrock_windows.cpp index fcc5c20a..829c909a 100644 --- a/source/gui/detail/bedrock_windows.cpp +++ b/source/gui/detail/bedrock_windows.cpp @@ -18,7 +18,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/source/gui/msgbox.cpp b/source/gui/msgbox.cpp index d11816fa..1c825da1 100644 --- a/source/gui/msgbox.cpp +++ b/source/gui/msgbox.cpp @@ -12,7 +12,9 @@ * James Bremner */ -#include +#include +#include +#include #include #include #include diff --git a/source/gui/timer.cpp b/source/gui/timer.cpp index 52981a8e..970aa5ab 100644 --- a/source/gui/timer.cpp +++ b/source/gui/timer.cpp @@ -43,8 +43,6 @@ namespace nana class timer_driver { - typedef std::lock_guard lock_guard; - friend class timer_core; timer_driver() = default; @@ -70,7 +68,7 @@ namespace nana auto tmid = p; ::nana::detail::platform_spec::instance().set_timer(reinterpret_cast(tmid), ms, &timer_driver::_m_timer_proc); #endif - lock_guard lock(mutex_); + ::nana::internal_scope_guard lock; timer_table_[tmid].reset(p); return p; } @@ -82,7 +80,8 @@ namespace nana void destroy(timer_identifier tid) { - lock_guard lock(mutex_); + ::nana::internal_scope_guard lock; + auto i = timer_table_.find(tid); if (i != timer_table_.end()) { @@ -101,7 +100,6 @@ namespace nana static void _m_timer_proc(std::size_t id); #endif private: - std::recursive_mutex mutex_; std::map> timer_table_; }; @@ -141,21 +139,19 @@ namespace nana nana::basic_event & evt_elapse_; }; //end class timer_core + #if defined(NANA_WINDOWS) void __stdcall timer_driver::_m_timer_proc(HWND /*hwnd*/, UINT /*uMsg*/, UINT_PTR id, DWORD /*dwTime*/) #else void timer_driver::_m_timer_proc(std::size_t id) #endif { - auto & driver = instance(); + auto & time_tbl = instance().timer_table_; - lock_guard lock(driver.mutex_); -#if defined(NANA_WINDOWS) - auto i = driver.timer_table_.find(id); -#else - auto i = driver.timer_table_.find(reinterpret_cast(id)); -#endif - if (i == driver.timer_table_.end()) + ::nana::internal_scope_guard lock; + + auto i = time_tbl.find(id); + if (i == time_tbl.end()) return; arg_elapse arg; @@ -183,8 +179,7 @@ namespace nana timer::~timer() { - if (impl_->tm_core) - timer_driver::instance().destroy(impl_->tm_core->id()); + stop(); delete impl_; } diff --git a/source/gui/widgets/categorize.cpp b/source/gui/widgets/categorize.cpp index fc88b2cc..596d7cd3 100644 --- a/source/gui/widgets/categorize.cpp +++ b/source/gui/widgets/categorize.cpp @@ -1,7 +1,7 @@ /** * A Categorize Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -10,7 +10,7 @@ * @file nana/gui/widgets/categorize.cpp */ -#include +#include #include #include #include diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index c5ef5f85..816d4ee9 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -10,9 +10,9 @@ * @file: nana/gui/widgets/combox.cpp */ -#include -#include +#include #include +#include #include #include #include diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 43b7615e..460e28f4 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -15,7 +15,7 @@ * Benjamin Navarro(pr#81) * besh81(pr#130) * dankan1890(pr#158) - * ErrorFlynn(pr#418) + * ErrorFlynn(pr#418,pr#448,pr#454) * */ #include diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 389b39b9..078844aa 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -13,12 +13,13 @@ * dankan1890(pr#158) */ +#include +#include #include #include #include #include -#include #include #include //introduces tolower #include diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index e280aef8..103355b1 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -1,6 +1,6 @@ /* * Nana GUI Library Definition - * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -11,7 +11,8 @@ * the file contains the files required for running of Nana.GUI */ -#include +#include +#include #include #include #include diff --git a/source/unicode_bidi.cpp b/source/unicode_bidi.cpp index 7b054e10..f71645c5 100644 --- a/source/unicode_bidi.cpp +++ b/source/unicode_bidi.cpp @@ -1,3 +1,17 @@ +/* + * Unicode Bidi-Language Implementation + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com) + * + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * @file: nana/unicode_bidi.cpp + * @contributors: + * glavangeorge(pr#440) + + */ #include #include