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
* Tue Sep 12 2017 Alexei Takaseev <taf@altlinux.org> 2.6-alt19.1
- 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
# - test build (devel)
......
......@@ -106,19 +106,14 @@ namespace uniset
std::mutex wlist_mutex;
std::vector<EvWatcher*> wlist;
// очередь wather-ов для инициализации (добавления в обработку)
struct WatcherInfo
{
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;
// готовящийся Watcher..он может быть только один в единицу времени
// это гарантирует prep_mutex
EvWatcher* wprep = { nullptr };
ev::async evprep;
std::condition_variable prep_event;
std::mutex prep_mutex;
std::atomic_bool prep_notify = { false };
std::mutex looprunOK_mutex;
std::condition_variable looprunOK_event;
......
......@@ -54,42 +54,32 @@ namespace uniset
// ---------------------------------------------------------------------------
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);
auto result = p.get_future();
bool ret = true;
// взводим флаг
prep_notify = false;
// посылаем сигнал для обработки
if( !evprep.is_active() )
evprep.start();
// посылаем сигнал для обработки
evprep.send(); // будим default loop
// ждём инициализации
while( true )
// ожидаем обработки evprepare (которая будет в defaultLoop)
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;
break;
}
return ( prep_notify == true );
} );
if( status == future_status::ready )
{
if( result.valid() )
{
ret = result.get();
break;
}
}
}
// сбрасываем флаг
prep_notify = false;
// если wprep стал nullptr - значит evprepare отработал нормально
bool ret = ( wprep == nullptr );
wprep = nullptr;
wact_info = nullptr;
return ret;
}
// ---------------------------------------------------------------------------
......@@ -194,23 +184,31 @@ namespace uniset
{
if( EV_ERROR & revents )
{
// cerr << myname << "(CommonEventLoop::onPrepare): invalid event" << endl;
// cerr << myname << "(CommonEventLoop::onPrepare): invalid event" << endl;
return;
}
if( !wact_info )
return;
try
prep_notify = false;
{
wact_info->watcher->evprepare(loop);
wact_info->result.set_value(true);
}
catch( std::exception& ex )
{
cerr << "(CommonEventLoop::onPrepare): evprepare err: " << ex.what() << endl;
wact_info->result.set_value(false);
std::lock_guard<std::mutex> lock(prep_mutex);
if( wprep )
{
try
{
wprep->evprepare(loop);
wprep = nullptr;
}
catch( std::exception& ex )
{
cerr << "(CommonEventLoop::onPrepare): evprepare err: " << ex.what() << endl;
}
}
}
// будим всех ожидающих..
prep_notify = true;
prep_event.notify_all();
}
// -------------------------------------------------------------------------
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