Commit d48e4892 authored by Pavel Vainerman's avatar Pavel Vainerman

(CommonEventLoop): переделал механизм активации Wathcer-ов

на старый вариант на conditional_variable вместо promise/future
parent 07a7e00a
...@@ -511,6 +511,9 @@ rm -f %buildroot%_libdir/*.la ...@@ -511,6 +511,9 @@ rm -f %buildroot%_libdir/*.la
* Tue Sep 12 2017 Alexei Takaseev <taf@altlinux.org> 2.6-alt19.1 * Tue Sep 12 2017 Alexei Takaseev <taf@altlinux.org> 2.6-alt19.1
- Rebuild with poco 1.7.9 - Rebuild with poco 1.7.9
# * Fri Jun 02 2017 Pavel Vainerman <pv@altlinux.ru> 2.6-alt29
# - test build (devel)
# * Thu Jun 01 2017 Pavel Vainerman <pv@altlinux.ru> 2.6-alt27 # * Thu Jun 01 2017 Pavel Vainerman <pv@altlinux.ru> 2.6-alt27
# - test build (devel) # - test build (devel)
......
...@@ -106,19 +106,14 @@ namespace uniset ...@@ -106,19 +106,14 @@ namespace uniset
std::mutex wlist_mutex; std::mutex wlist_mutex;
std::vector<EvWatcher*> wlist; std::vector<EvWatcher*> wlist;
// очередь wather-ов для инициализации (добавления в обработку) // готовящийся Watcher..он может быть только один в единицу времени
struct WatcherInfo // это гарантирует prep_mutex
{ EvWatcher* wprep = { nullptr };
WatcherInfo( EvWatcher* w, std::promise<bool>& p ):
watcher(w),result(p){}
EvWatcher* watcher;
std::promise<bool>& result;
};
std::shared_ptr<WatcherInfo> wact_info = { nullptr };
std::mutex wact_mutex;
ev::async evprep; ev::async evprep;
std::condition_variable prep_event;
std::mutex prep_mutex;
std::atomic_bool prep_notify = { false };
std::mutex looprunOK_mutex; std::mutex looprunOK_mutex;
std::condition_variable looprunOK_event; std::condition_variable looprunOK_event;
......
...@@ -54,42 +54,32 @@ namespace uniset ...@@ -54,42 +54,32 @@ namespace uniset
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
bool CommonEventLoop::activateWatcher( EvWatcher* w, size_t waitTimeout_msec ) bool CommonEventLoop::activateWatcher( EvWatcher* w, size_t waitTimeout_msec )
{ {
std::lock_guard<std::mutex> l(wact_mutex); // готовим "указатель" на объект требующий активации
std::unique_lock<std::mutex> locker(prep_mutex);
wprep = w;
std::promise<bool> p; // взводим флаг
wact_info = std::make_shared<WatcherInfo>(w,p); prep_notify = false;
auto result = p.get_future();
bool ret = true;
// посылаем сигнал для обработки
if( !evprep.is_active() ) if( !evprep.is_active() )
evprep.start(); evprep.start();
// посылаем сигнал для обработки
evprep.send(); // будим default loop evprep.send(); // будим default loop
// ждём инициализации // ожидаем обработки evprepare (которая будет в defaultLoop)
while( true ) prep_event.wait_for(locker, std::chrono::milliseconds(waitTimeout_msec), [ = ]()
{
auto status = result.wait_for(std::chrono::milliseconds(waitTimeout_msec));
if( status == future_status::timeout )
{ {
ret = false; return ( prep_notify == true );
break; } );
}
if( status == future_status::ready ) // сбрасываем флаг
{ prep_notify = false;
if( result.valid() )
{ // если wprep стал nullptr - значит evprepare отработал нормально
ret = result.get(); bool ret = ( wprep == nullptr );
break; wprep = nullptr;
}
}
}
wact_info = nullptr;
return ret; return ret;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -194,24 +184,32 @@ namespace uniset ...@@ -194,24 +184,32 @@ namespace uniset
{ {
if( EV_ERROR & revents ) if( EV_ERROR & revents )
{ {
// cerr << myname << "(CommonEventLoop::onPrepare): invalid event" << endl; // cerr << myname << "(CommonEventLoop::onPrepare): invalid event" << endl;
return; return;
} }
if( !wact_info ) prep_notify = false;
return; {
std::lock_guard<std::mutex> lock(prep_mutex);
if( wprep )
{
try try
{ {
wact_info->watcher->evprepare(loop); wprep->evprepare(loop);
wact_info->result.set_value(true); wprep = nullptr;
} }
catch( std::exception& ex ) catch( std::exception& ex )
{ {
cerr << "(CommonEventLoop::onPrepare): evprepare err: " << ex.what() << endl; cerr << "(CommonEventLoop::onPrepare): evprepare err: " << ex.what() << endl;
wact_info->result.set_value(false);
} }
} }
}
// будим всех ожидающих..
prep_notify = true;
prep_event.notify_all();
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void CommonEventLoop::onStop( ev::async& aw, int revents ) noexcept void CommonEventLoop::onStop( ev::async& aw, int revents ) noexcept
{ {
......
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