Commit 8eade6a3 authored by Pavel Vainerman's avatar Pavel Vainerman

(CommonEventLoop): переписал немного процесс активации

(попытка решить проблемму с "зависанием")
parent 35db506e
......@@ -16,7 +16,7 @@
Name: libuniset2
Version: 2.6
Release: alt2
Release: alt3
Summary: UniSet - library for building distributed industrial control systems
License: LGPL
......@@ -508,6 +508,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# history of current unpublished changes
%changelog
* Tue Nov 22 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt3
- CommonEventLoop: refactoring prepare process
* Mon Nov 21 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt2
- UNet: fixed bug in change receive channel
......
......@@ -58,8 +58,14 @@ class CommonEventLoop
bool evIsActive() const noexcept;
/*! \return TRUE - если всё удалось. return актуален только для случая когда thread = true */
bool evrun( EvWatcher* w, bool thread = true );
/*! \return TRUE - если всё удалось. return актуален только для случая когда thread = true
* \param thread - создать отдельный (асинхронный) поток для event loop.
* Если thread=false - функция не вернёт управление и будет ждать завершения работы ( см. evstop())
* \param waitPrepareTimeout_msec - сколько ждать активации, либо функция вернёт false.
* Даже если thread = false, но wather не сможет быть "активирован" функция вернёт управление
* с return false.
*/
bool evrun( EvWatcher* w, bool thread = true, size_t waitPrepareTimeout_msec = 5000);
/*! \return TRUE - если это был последний EvWatcher и loop остановлен */
bool evstop( EvWatcher* w );
......@@ -83,6 +89,7 @@ class CommonEventLoop
ev::dynamic_loop loop;
ev::async evterm;
std::shared_ptr<std::thread> thr;
std::mutex thr_mutex;
std::mutex term_mutex;
std::condition_variable term_event;
......
......@@ -31,7 +31,7 @@ CommonEventLoop::~CommonEventLoop()
}
}
// ---------------------------------------------------------------------------
bool CommonEventLoop::evrun(EvWatcher* w, bool thread )
bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec )
{
if( !w )
return false;
......@@ -39,7 +39,7 @@ bool CommonEventLoop::evrun(EvWatcher* w, bool thread )
bool ret = false;
{
{
std::unique_lock<std::mutex> l(wlist_mutex);
std::lock_guard<std::mutex> lck(wlist_mutex);
for( auto& e: wlist )
{
if( e == w )
......@@ -51,25 +51,43 @@ bool CommonEventLoop::evrun(EvWatcher* w, bool thread )
wlist.push_back(w);
}
if( !thr )
{
thr = make_shared<std::thread>( [ = ] { CommonEventLoop::defaultLoop(); } );
std::this_thread::sleep_for(std::chrono::milliseconds(30));
std::lock_guard<std::mutex> lck(thr_mutex);
if( !thr )
{
thr = make_shared<std::thread>( [ = ] { CommonEventLoop::defaultLoop(); } );
std::unique_lock<std::mutex> locker(prep_mutex);
// ожидаем запуска loop
// иначе evprep.send() улетит в никуда
prep_event.wait_for(locker,std::chrono::milliseconds(waitTimeout_msec), [=]()
{
return (isrunning == false);
} );
if( !isrunning )
{
cerr << "(CommonEventLoop::evrun): " << w->wname() << " evloop NOT RUN!.." << endl;
return false;
}
}
}
// готовим "указатель" на объект требующий активации
std::unique_lock<std::mutex> locker(prep_mutex);
wprep = w;
// взводим флаг
prep_notify = false;
// посылаем сигнал для обработки
evprep.send(); // будим default loop
// ожидаем обработки evprepare (которая будет в defaultLoop)
while( !prep_notify )
prep_event.wait_for(locker,std::chrono::milliseconds(waitTimeout_msec), [=]()
{
prep_event.wait_for(locker,std::chrono::milliseconds(5000), [=]()
{
return (prep_notify == true);
} );
}
return (prep_notify == true);
} );
// сбрасываем флаг
prep_notify = false;
......@@ -105,7 +123,7 @@ bool CommonEventLoop::evstop( EvWatcher* w )
if( !w )
return false;
std::unique_lock<std::mutex> l(wlist_mutex);
std::lock_guard<std::mutex> l(wlist_mutex);
try
{
......@@ -143,7 +161,7 @@ void CommonEventLoop::onPrepare() noexcept
{
prep_notify = false;
{
std::unique_lock<std::mutex> lock(prep_mutex);
std::lock_guard<std::mutex> lock(prep_mutex);
if( wprep )
{
try
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment