diff --git a/include/nana/threads/pool.hpp b/include/nana/threads/pool.hpp index 16edac1f..38d9952e 100644 --- a/include/nana/threads/pool.hpp +++ b/include/nana/threads/pool.hpp @@ -54,11 +54,17 @@ namespace threads struct task_signal; class impl; + + pool(const pool&) = delete; + pool& operator=(const pool&) = delete; public: pool(); ///< Creates a group of threads. + pool(pool&&); pool(std::size_t thread_number); ///< Creates a number of threads specifed by thread_number. ~pool(); ///< waits for the all running tasks till they are finished and skips all the queued tasks. + pool& operator=(pool&&); + template void push(const Function& f) { diff --git a/source/gui/detail/bedrock_posix.cpp b/source/gui/detail/bedrock_posix.cpp index 3282a32e..4f74f5a9 100644 --- a/source/gui/detail/bedrock_posix.cpp +++ b/source/gui/detail/bedrock_posix.cpp @@ -1158,7 +1158,9 @@ namespace detail } ++(context->event_pump_ref_count); - wd_manager().internal_lock().revert(); + + auto & lock = wd_manager().internal_lock(); + lock.revert(); native_window_type owner_native = 0; core_window_t * owner = 0; @@ -1183,8 +1185,9 @@ namespace detail owner->flags.enabled = true; native_interface::enable_window(owner_native, true); } - - wd_manager().internal_lock().forward(); + + lock.forward(); + if(0 == --(context->event_pump_ref_count)) { if(0 == modal_window || 0 == context->window_count) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 984988ee..e301ca5e 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -335,7 +335,7 @@ namespace detail void window_manager::revertible_mutex::revert() { - if(impl_->thread.ref && (impl_->thread.tid == nana::system::this_thread_id())) + if(impl_->thread.tid == nana::system::this_thread_id()) { std::size_t cnt = impl_->thread.ref; @@ -346,24 +346,30 @@ namespace detail for (std::size_t i = 0; i < cnt; ++i) impl_->mutex.unlock(); } + else + throw std::runtime_error("The revert is not allowed"); } void window_manager::revertible_mutex::forward() { impl_->mutex.lock(); + if(impl_->invoke_stack.size()) { auto thr = impl_->invoke_stack.back(); + + impl_->invoke_stack.pop_back(); + if(thr.tid == nana::system::this_thread_id()) { - impl_->invoke_stack.pop_back(); for (std::size_t i = 0; i < thr.ref; ++i) impl_->mutex.lock(); impl_->thread = thr; } else - throw std::runtime_error("Nana.GUI: The forward is not matched."); + throw std::runtime_error("The forward is not matched. Please report this issue"); } + impl_->mutex.unlock(); } //end class revertible_mutex diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 94446c8b..486e6fae 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -992,33 +992,30 @@ namespace API void modal_window(window wd) { + auto const iwd = reinterpret_cast(wd); + internal_scope_guard isg; + + if (!restrict::wd_manager().available(iwd)) + return; + + if ((iwd->other.category == category::flags::root) && (iwd->flags.modal == false)) { - auto const iwd = reinterpret_cast(wd); - internal_scope_guard isg; - - if (!restrict::wd_manager().available(iwd)) - return; - - if ((iwd->other.category == category::flags::root) && (iwd->flags.modal == false)) - { - iwd->flags.modal = true; + iwd->flags.modal = true; #if defined(NANA_X11) - interface_type::set_modal(iwd->root); + interface_type::set_modal(iwd->root); #endif - restrict::wd_manager().show(iwd, true); - } - else - return; + restrict::wd_manager().show(iwd, true); } + else + return; - //modal has to guarantee that does not lock the mutex of window_manager before invokeing the pump_event, - //otherwise, the modal will prevent the other thread access the window. restrict::bedrock.pump_event(wd, true); } void wait_for(window wd) { - if (wd) + internal_scope_guard lock; + if (restrict::wd_manager().available(reinterpret_cast(wd))) restrict::bedrock.pump_event(wd, false); } diff --git a/source/gui/wvl.cpp b/source/gui/wvl.cpp index 33f027f3..27e7e5ea 100644 --- a/source/gui/wvl.cpp +++ b/source/gui/wvl.cpp @@ -46,6 +46,7 @@ namespace nana void pump() { + internal_scope_guard lock; detail::bedrock::instance().pump_event(nullptr, false); } diff --git a/source/threads/pool.cpp b/source/threads/pool.cpp index f1237887..0e2c6c29 100644 --- a/source/threads/pool.cpp +++ b/source/threads/pool.cpp @@ -356,11 +356,28 @@ namespace threads { } + pool::pool(pool&& other) + : pool() + { + std::swap(impl_, other.impl_); + } + pool::pool(std::size_t thread_number) : impl_(new impl(thread_number)) { } + pool& pool::operator=(pool&& other) + { + if(this != &other) + { + delete impl_; + impl_ = other.impl_; + other.impl_ = new impl(4); + } + return *this; + } + pool::~pool() { delete impl_;