Commit d5b8a3d2 authored by Pavel Vainerman's avatar Pavel Vainerman

(EventLoop): исправил ошибку в wait_for(),

рефакторинг UNetExchange, правка тестов.
parent 8eade6a3
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
Name: libuniset2 Name: libuniset2
Version: 2.6 Version: 2.6
Release: alt3 Release: alt3.1
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
License: LGPL License: LGPL
...@@ -508,6 +508,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -508,6 +508,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# history of current unpublished changes # history of current unpublished changes
%changelog %changelog
* Tue Nov 22 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt3.1
- CommonEventLoop: refactoring prepare process (part. 2)
* Tue Nov 22 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt3 * Tue Nov 22 2016 Pavel Vainerman <pv@altlinux.ru> 2.6-alt3
- CommonEventLoop: refactoring prepare process - CommonEventLoop: refactoring prepare process
......
...@@ -955,7 +955,18 @@ uniset::SimpleInfo* UNetExchange::getInfo( CORBA::Long userparam ) ...@@ -955,7 +955,18 @@ uniset::SimpleInfo* UNetExchange::getInfo( CORBA::Long userparam )
inf << i->info << endl; inf << i->info << endl;
inf << vmon.pretty_str() << endl; inf << vmon.pretty_str() << endl;
inf << endl; inf << endl;
inf << "LogServer: " << logserv_host << ":" << logserv_port << endl;
if( logserv )
{
inf << "LogServer: " << logserv_host << ":" << logserv_port
<< ( logserv->isRunning() ? " [RUNNIG]" : " [STOPPED]" )
<< endl
<< " " << logserv->getShortInfo()
<< endl;
}
else
inf << "LogServer: NONE" << endl;
inf << endl; inf << endl;
inf << "Receivers: " << endl; inf << "Receivers: " << endl;
......
...@@ -198,9 +198,12 @@ TEST_CASE("[UNetUDP]: respond sensor", "[unetudp]") ...@@ -198,9 +198,12 @@ TEST_CASE("[UNetUDP]: respond sensor", "[unetudp]")
{ {
InitTest(); InitTest();
// в запускающем файле стоит --unet-recv-timeout 2000
msleep(2500);
ObjectId node1_not_respond_s = 1; ObjectId node1_not_respond_s = 1;
CHECK( ui->getValue(node1_not_respond_s) == 0 );
// в запускающем файле стоит --unet-recv-timeout 1000
// ждём больше, чтобы сработал timeout
msleep(5000);
REQUIRE( ui->getValue(node1_not_respond_s) == 1 ); REQUIRE( ui->getValue(node1_not_respond_s) == 1 );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -295,7 +298,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]") ...@@ -295,7 +298,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]")
REQUIRE( ui->getValue(11) == 0 ); REQUIRE( ui->getValue(11) == 0 );
send(pack); send(pack);
msleep(120); msleep(200);
REQUIRE( ui->getValue(8) == 100 ); REQUIRE( ui->getValue(8) == 100 );
REQUIRE( ui->getValue(9) == -100 ); REQUIRE( ui->getValue(9) == -100 );
REQUIRE( ui->getValue(10) == 1 ); REQUIRE( ui->getValue(10) == 1 );
...@@ -313,7 +316,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]") ...@@ -313,7 +316,7 @@ TEST_CASE("[UNetUDP]: check receiver", "[unetudp][receiver]")
pack.addDData(10, false); pack.addDData(10, false);
pack.addDData(11, true); pack.addDData(11, true);
send(pack); send(pack);
msleep(120); msleep(200);
REQUIRE( ui->getValue(8) == 10 ); REQUIRE( ui->getValue(8) == 10 );
REQUIRE( ui->getValue(9) == -10 ); REQUIRE( ui->getValue(9) == -10 );
REQUIRE( ui->getValue(10) == 0 ); REQUIRE( ui->getValue(10) == 0 );
......
...@@ -35,14 +35,14 @@ ...@@ -35,14 +35,14 @@
<nodes port="2809" unet_broadcast_ip="127.255.255.255" unet_broadcast_ip2="badip"> <nodes port="2809" unet_broadcast_ip="127.255.255.255" unet_broadcast_ip2="badip">
<item id="3000" ip="127.0.0.1" name="localhost" textname="Локальный узел" unet_ignore="0" unet_port="3000"/> <item id="3000" ip="127.0.0.1" name="localhost" textname="Локальный узел" unet_ignore="0" unet_port="3000"/>
<item id="3001" ip="127.0.0.1" name="localhost1" textname="Локальный узел" unet_ignore="1" unet_port="3001"/> <item id="3001" ip="127.0.0.1" name="localhost1" textname="Локальный узел" unet_ignore="1" unet_port="3001"/>
<item id="3002" ip="192.168.56.10" name="Node1" textname="Node1" unet_ignore="0" unet_ip="192.168.56.255" unet_respond_id="Node1_Respond_S" unet_respond_invert="1"/> <item id="3002" ip="192.168.56.10" name="Node1" textname="Node1" unet_ignore="0" unet_respond_id="Node1_Not_Respond_S" unet_respond_invert="1"/>
<item id="3003" ip="192.168.56.11" name="Node2" textname="Node2" unet_ignore="0" unet_ip="192.168.56.255" unet_respond_id="Node2_Respond_S" unet_lostpackets_id="Node2_LostPackets_AS" unet_numchannel_id="Node2_NumChannel_AS"/> <item id="3003" ip="192.168.56.11" name="Node2" textname="Node2" unet_ignore="0" unet_respond_id="Node2_Respond_S" unet_lostpackets_id="Node2_LostPackets_AS" unet_numchannel_id="Node2_NumChannel_AS"/>
</nodes> </nodes>
<!-- ************************ Датчики ********************** --> <!-- ************************ Датчики ********************** -->
<sensors name="Sensors"> <sensors name="Sensors">
<item id="100" iotype="DI" name="TestMode_S" textname="Test sensor"/> <item id="100" iotype="DI" name="TestMode_S" textname="Test sensor"/>
<item id="1" iotype="DI" name="Node1_Respond_S" textname="Node1 respond"/> <item id="1" iotype="DI" name="Node1_Not_Respond_S" textname="Node1 not respond"/>
<item id="2" iotype="AI" name="AI1_S" textname="AI sensor 1" unet="1" default="1"/> <item id="2" iotype="AI" name="AI1_S" textname="AI sensor 1" unet="1" default="1"/>
<item id="3" iotype="AI" name="AI2_S" textname="AI sensor 2" unet="1" default="2"/> <item id="3" iotype="AI" name="AI2_S" textname="AI sensor 2" unet="1" default="2"/>
<item id="4" iotype="AI" name="AI3_S" textname="AI sensor 3" unet="1" default="3"/> <item id="4" iotype="AI" name="AI3_S" textname="AI sensor 3" unet="1" default="3"/>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
#include <list> #include <vector>
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
namespace uniset namespace uniset
{ {
...@@ -65,7 +65,7 @@ class CommonEventLoop ...@@ -65,7 +65,7 @@ class CommonEventLoop
* Даже если thread = false, но wather не сможет быть "активирован" функция вернёт управление * Даже если thread = false, но wather не сможет быть "активирован" функция вернёт управление
* с return false. * с return false.
*/ */
bool evrun( EvWatcher* w, bool thread = true, size_t waitPrepareTimeout_msec = 5000); bool evrun( EvWatcher* w, bool thread = true, size_t waitPrepareTimeout_msec = 8000);
/*! \return TRUE - если это был последний EvWatcher и loop остановлен */ /*! \return TRUE - если это был последний EvWatcher и loop остановлен */
bool evstop( EvWatcher* w ); bool evstop( EvWatcher* w );
...@@ -75,6 +75,9 @@ class CommonEventLoop ...@@ -75,6 +75,9 @@ class CommonEventLoop
return loop; return loop;
} }
// количество зарегистрированных wather-ов
size_t size() const;
protected: protected:
private: private:
...@@ -96,7 +99,7 @@ class CommonEventLoop ...@@ -96,7 +99,7 @@ class CommonEventLoop
std::atomic_bool term_notify = { false }; std::atomic_bool term_notify = { false };
std::mutex wlist_mutex; std::mutex wlist_mutex;
std::list<EvWatcher*> wlist; std::vector<EvWatcher*> wlist;
// готовящийся Watcher..он может быть только один в единицу времени // готовящийся Watcher..он может быть только один в единицу времени
// это гарантирует prep_mutex // это гарантирует prep_mutex
......
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
#include <algorithm>
#include "CommonEventLoop.h" #include "CommonEventLoop.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
using namespace std; using namespace std;
...@@ -33,20 +34,17 @@ CommonEventLoop::~CommonEventLoop() ...@@ -33,20 +34,17 @@ CommonEventLoop::~CommonEventLoop()
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec ) bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec )
{ {
if( !w ) if( w == nullptr )
return false; return false;
bool ret = false; bool ret = false;
{ {
{ {
std::lock_guard<std::mutex> lck(wlist_mutex); std::lock_guard<std::mutex> lck(wlist_mutex);
for( auto& e: wlist ) if( std::find(wlist.begin(), wlist.end(), w) != wlist.end() )
{ {
if( e == w ) cerr << "(CommonEventLoop::evrun): " << w->wname() << " ALREADY ADDED.." << endl;
{ return false;
cerr << "(CommonEventLoop::evrun): " << w->wname() << " ALREADY ADDED.." << endl;
return false;
}
} }
wlist.push_back(w); wlist.push_back(w);
} }
...@@ -62,7 +60,7 @@ bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec ...@@ -62,7 +60,7 @@ bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec
// иначе evprep.send() улетит в никуда // иначе evprep.send() улетит в никуда
prep_event.wait_for(locker,std::chrono::milliseconds(waitTimeout_msec), [=]() prep_event.wait_for(locker,std::chrono::milliseconds(waitTimeout_msec), [=]()
{ {
return (isrunning == false); return ( isrunning == true );
} ); } );
if( !isrunning ) if( !isrunning )
...@@ -70,6 +68,10 @@ bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec ...@@ -70,6 +68,10 @@ bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec
cerr << "(CommonEventLoop::evrun): " << w->wname() << " evloop NOT RUN!.." << endl; cerr << "(CommonEventLoop::evrun): " << w->wname() << " evloop NOT RUN!.." << endl;
return false; return false;
} }
// небольшая пауза после запуск event loop
// чтобы "надёжнее" сработал evprep.send() (см. ниже)
std::this_thread::sleep_for(std::chrono::milliseconds(50));
} }
} }
...@@ -86,7 +88,7 @@ bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec ...@@ -86,7 +88,7 @@ bool CommonEventLoop::evrun( EvWatcher* w, bool thread, size_t waitTimeout_msec
// ожидаем обработки evprepare (которая будет в defaultLoop) // ожидаем обработки evprepare (которая будет в defaultLoop)
prep_event.wait_for(locker,std::chrono::milliseconds(waitTimeout_msec), [=]() prep_event.wait_for(locker,std::chrono::milliseconds(waitTimeout_msec), [=]()
{ {
return (prep_notify == true); return ( prep_notify == true );
} ); } );
// сбрасываем флаг // сбрасываем флаг
...@@ -134,7 +136,8 @@ bool CommonEventLoop::evstop( EvWatcher* w ) ...@@ -134,7 +136,8 @@ bool CommonEventLoop::evstop( EvWatcher* w )
cerr << "(CommonEventLoop::evfinish): evfinish err: " << ex.what() << endl; cerr << "(CommonEventLoop::evfinish): evfinish err: " << ex.what() << endl;
} }
wlist.remove(w); wlist.erase( std::remove( wlist.begin(), wlist.end(), w ), wlist.end() );
// wlist.remove(w);
if( !wlist.empty() ) if( !wlist.empty() )
return false; return false;
...@@ -157,6 +160,11 @@ bool CommonEventLoop::evstop( EvWatcher* w ) ...@@ -157,6 +160,11 @@ bool CommonEventLoop::evstop( EvWatcher* w )
return true; return true;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
size_t CommonEventLoop::size() const
{
return wlist.size();
}
// -------------------------------------------------------------------------
void CommonEventLoop::onPrepare() noexcept void CommonEventLoop::onPrepare() noexcept
{ {
prep_notify = false; prep_notify = false;
...@@ -208,11 +216,11 @@ void CommonEventLoop::onStop() noexcept ...@@ -208,11 +216,11 @@ void CommonEventLoop::onStop() noexcept
void CommonEventLoop::defaultLoop() noexcept void CommonEventLoop::defaultLoop() noexcept
{ {
isrunning = true;
evterm.start(); evterm.start();
evprep.start(); evprep.start();
isrunning = true;
while( !cancelled ) while( !cancelled )
{ {
try try
......
...@@ -109,9 +109,7 @@ TEST_CASE("UniSetTimer: conv to Poco", "[PassiveTimer][poco]" ) ...@@ -109,9 +109,7 @@ TEST_CASE("UniSetTimer: conv to Poco", "[PassiveTimer][poco]" )
{ {
Poco::Timespan tm = UniSetTimer::millisecToPoco(UniSetTimer::WaitUpTime); Poco::Timespan tm = UniSetTimer::millisecToPoco(UniSetTimer::WaitUpTime);
REQUIRE( tm.seconds() == -1 ); REQUIRE( tm.days() == 12443823 /* std::numeric_limits<int>::max() */ );
REQUIRE( tm.microseconds() == 0 );
REQUIRE( tm.totalMilliseconds() < 0 );
} }
{ {
...@@ -125,9 +123,7 @@ TEST_CASE("UniSetTimer: conv to Poco", "[PassiveTimer][poco]" ) ...@@ -125,9 +123,7 @@ TEST_CASE("UniSetTimer: conv to Poco", "[PassiveTimer][poco]" )
// usec --> Poco::Timespan // usec --> Poco::Timespan
{ {
Poco::Timespan tm = UniSetTimer::microsecToPoco(UniSetTimer::WaitUpTime); Poco::Timespan tm = UniSetTimer::microsecToPoco(UniSetTimer::WaitUpTime);
REQUIRE( tm.seconds() == -1 ); REQUIRE( tm.days() == 12443823 /* std::numeric_limits<int>::max() */ );
REQUIRE( tm.microseconds() == 0 );
REQUIRE( tm.totalMilliseconds() < 0 );
} }
{ {
Poco::Timespan tm = UniSetTimer::microsecToPoco(2000000); Poco::Timespan tm = UniSetTimer::microsecToPoco(2000000);
......
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