fix the revertable lock of window_manager
This commit is contained in:
parent
01ff1c11c1
commit
9ed5e81ca2
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user