fix the revertable lock of window_manager

This commit is contained in:
Jinhao 2016-10-19 02:58:49 +08:00
parent 01ff1c11c1
commit 9ed5e81ca2
6 changed files with 53 additions and 23 deletions

View File

@ -54,11 +54,17 @@ namespace threads
struct task_signal; struct task_signal;
class impl; class impl;
pool(const pool&) = delete;
pool& operator=(const pool&) = delete;
public: public:
pool(); ///< Creates a group of threads. pool(); ///< Creates a group of threads.
pool(pool&&);
pool(std::size_t thread_number); ///< Creates a number of threads specifed by thread_number. 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(); ///< waits for the all running tasks till they are finished and skips all the queued tasks.
pool& operator=(pool&&);
template<typename Function> template<typename Function>
void push(const Function& f) void push(const Function& f)
{ {

View File

@ -1158,7 +1158,9 @@ namespace detail
} }
++(context->event_pump_ref_count); ++(context->event_pump_ref_count);
wd_manager().internal_lock().revert();
auto & lock = wd_manager().internal_lock();
lock.revert();
native_window_type owner_native = 0; native_window_type owner_native = 0;
core_window_t * owner = 0; core_window_t * owner = 0;
@ -1184,7 +1186,8 @@ namespace detail
native_interface::enable_window(owner_native, true); native_interface::enable_window(owner_native, true);
} }
wd_manager().internal_lock().forward(); lock.forward();
if(0 == --(context->event_pump_ref_count)) if(0 == --(context->event_pump_ref_count))
{ {
if(0 == modal_window || 0 == context->window_count) if(0 == modal_window || 0 == context->window_count)

View File

@ -335,7 +335,7 @@ namespace detail
void window_manager::revertible_mutex::revert() 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; std::size_t cnt = impl_->thread.ref;
@ -346,24 +346,30 @@ namespace detail
for (std::size_t i = 0; i < cnt; ++i) for (std::size_t i = 0; i < cnt; ++i)
impl_->mutex.unlock(); impl_->mutex.unlock();
} }
else
throw std::runtime_error("The revert is not allowed");
} }
void window_manager::revertible_mutex::forward() void window_manager::revertible_mutex::forward()
{ {
impl_->mutex.lock(); impl_->mutex.lock();
if(impl_->invoke_stack.size()) if(impl_->invoke_stack.size())
{ {
auto thr = impl_->invoke_stack.back(); auto thr = impl_->invoke_stack.back();
impl_->invoke_stack.pop_back();
if(thr.tid == nana::system::this_thread_id()) if(thr.tid == nana::system::this_thread_id())
{ {
impl_->invoke_stack.pop_back();
for (std::size_t i = 0; i < thr.ref; ++i) for (std::size_t i = 0; i < thr.ref; ++i)
impl_->mutex.lock(); impl_->mutex.lock();
impl_->thread = thr; impl_->thread = thr;
} }
else 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(); impl_->mutex.unlock();
} }
//end class revertible_mutex //end class revertible_mutex

View File

@ -991,7 +991,6 @@ namespace API
} }
void modal_window(window wd) void modal_window(window wd)
{
{ {
auto const iwd = reinterpret_cast<basic_window*>(wd); auto const iwd = reinterpret_cast<basic_window*>(wd);
internal_scope_guard isg; internal_scope_guard isg;
@ -1009,16 +1008,14 @@ namespace API
} }
else else
return; 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); restrict::bedrock.pump_event(wd, true);
} }
void wait_for(window wd) void wait_for(window wd)
{ {
if (wd) internal_scope_guard lock;
if (restrict::wd_manager().available(reinterpret_cast<basic_window*>(wd)))
restrict::bedrock.pump_event(wd, false); restrict::bedrock.pump_event(wd, false);
} }

View File

@ -46,6 +46,7 @@ namespace nana
void pump() void pump()
{ {
internal_scope_guard lock;
detail::bedrock::instance().pump_event(nullptr, false); detail::bedrock::instance().pump_event(nullptr, false);
} }

View File

@ -356,11 +356,28 @@ namespace threads
{ {
} }
pool::pool(pool&& other)
: pool()
{
std::swap(impl_, other.impl_);
}
pool::pool(std::size_t thread_number) pool::pool(std::size_t thread_number)
: impl_(new impl(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() pool::~pool()
{ {
delete impl_; delete impl_;