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;
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<typename Function>
void push(const Function& f)
{

View File

@ -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)

View File

@ -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

View File

@ -992,33 +992,30 @@ namespace API
void modal_window(window wd)
{
auto const iwd = reinterpret_cast<basic_window*>(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<basic_window*>(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<basic_window*>(wd)))
restrict::bedrock.pump_event(wd, false);
}

View File

@ -46,6 +46,7 @@ namespace nana
void pump()
{
internal_scope_guard lock;
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)
: 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_;