Commit 12cca635 authored by Pavel Vainerman's avatar Pavel Vainerman

backported to p8 as 2.5-alt18.M80P.19 (with rpmbph script)

parents 9f6a6de2 d2ae7b28
......@@ -41,8 +41,8 @@ static struct option longopts[] =
{ "start", no_argument, 0, 's' },
{ "finish", no_argument, 0, 'f' },
{ "foldUp", no_argument, 0, 'u' },
{ "configure", required_argument, 0, 'r' },
{ "logrotate", required_argument, 0, 'l' },
{ "configure", optional_argument, 0, 'r' },
{ "logrotate", optional_argument, 0, 'l' },
{ "info", required_argument, 0, 'i' },
{ "setValue", required_argument, 0, 'x' },
{ "getValue", required_argument, 0, 'g' },
......@@ -60,6 +60,7 @@ string conffile("configure.xml");
// --------------------------------------------------------------------------
static bool commandToAll( const string& section, std::shared_ptr<ObjectRepository>& rep, Command cmd );
static void createSections(const std::shared_ptr<Configuration>& c );
static void errDoNotReolve( const std::string& oname );
// --------------------------------------------------------------------------
int omap();
int configure( const string& args, UInterface& ui );
......@@ -183,7 +184,8 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return setValue(optarg, ui);
string name = ( optarg ) ? optarg : "";
return setValue(name, ui);
}
break;
......@@ -193,7 +195,8 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getValue(optarg, ui);
string name = ( optarg ) ? optarg : "";
return getValue(name, ui);
}
break;
......@@ -203,7 +206,8 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getRawValue(optarg, ui);
string name = ( optarg ) ? optarg : "";
return getRawValue(name, ui);
}
break;
......@@ -212,7 +216,8 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getChangedTime(optarg, ui);
string name = ( optarg ) ? optarg : "";
return getChangedTime(name, ui);
}
break;
......@@ -270,7 +275,8 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return configure(optarg, ui);
string name = ( optarg ) ? optarg : "";
return configure(name, ui);
}
break;
......@@ -298,7 +304,8 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return logRotate(optarg, ui);
string name = ( optarg ) ? optarg : "";
return logRotate(name, ui);
}
break;
......@@ -308,7 +315,8 @@ int main(int argc, char** argv)
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(UniSetTypes::AdminID);
return getCalibrate(optarg, ui);
string name = ( optarg ) ? optarg : "";
return getCalibrate(name, ui);
}
break;
......@@ -365,6 +373,11 @@ int main(int argc, char** argv)
cerr << " mesg: " << fe.errmsg() << endl;
}
}
catch( std::exception& ex )
{
if( !quiet )
cerr << "exception: " << ex.what() << endl;
}
catch(...)
{
if( !quiet )
......@@ -418,7 +431,11 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
{
case StartUp:
{
if(CORBA::is_nil(obj)) break;
if( CORBA::is_nil(obj) )
{
errDoNotReolve(ob);
break;
}
SystemMessage msg(SystemMessage::StartUp);
obj->push( Message::transport(msg) );
......@@ -430,7 +447,11 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
case FoldUp:
{
if(CORBA::is_nil(obj)) break;
if(CORBA::is_nil(obj))
{
errDoNotReolve(ob);
break;
}
SystemMessage msg(SystemMessage::FoldUp);
obj->push( Message::transport(msg) );
......@@ -442,7 +463,11 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
case Finish:
{
if(CORBA::is_nil(obj)) break;
if(CORBA::is_nil(obj))
{
errDoNotReolve(ob);
break;
}
SystemMessage msg(SystemMessage::Finish);
obj->push( Message::transport(msg) );
......@@ -511,6 +536,9 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
}
catch( ORepFailed )
{
if( !quiet )
cerr << "..ORepFailed.." << endl;
cout.setf(old_flags);
return false;
}
......@@ -875,7 +903,7 @@ int logRotate( const string& arg, UInterface& ui )
auto conf = ui.getConf();
// посылка всем
if( arg.empty() || (arg.c_str())[0] != '-' )
if( arg.empty() || arg[0] == '-' )
{
auto rep = make_shared<ObjectRepository>(conf);
commandToAll(conf->getServicesSection(), rep, (Command)LogRotate);
......@@ -884,12 +912,16 @@ int logRotate( const string& arg, UInterface& ui )
}
else // посылка определённому объекту
{
UniSetTypes::ObjectId id = conf->oind->getIdByName(arg);
UniSetTypes::ObjectId id = conf->getObjectID(arg);
if( id == DefaultObjectId )
id = conf->getControllerID(arg);
else if( id == DefaultObjectId )
id = conf->getServiceID(arg);
if( id == DefaultObjectId )
{
if( !quiet )
cout << "(logrotate): name='" << arg << "' не найдено!!!\n";
cout << "(logrotate): not found ID for name='" << arg << "'" << endl;
return 1;
}
......@@ -911,7 +943,7 @@ int configure( const string& arg, UInterface& ui )
auto conf = ui.getConf();
// посылка всем
if( arg.empty() || (arg.c_str())[0] != '-' )
if( arg.empty() || arg[0] == '-' )
{
auto rep = make_shared<ObjectRepository>(conf);
commandToAll(conf->getServicesSection(), rep, (Command)Configure);
......@@ -920,7 +952,12 @@ int configure( const string& arg, UInterface& ui )
}
else // посылка определённому объекту
{
UniSetTypes::ObjectId id = conf->oind->getIdByName(arg);
UniSetTypes::ObjectId id = conf->getObjectID(arg);
if( id == DefaultObjectId )
id = conf->getControllerID(arg);
if( id == DefaultObjectId )
id = conf->getServiceID(arg);
if( id == DefaultObjectId )
{
......@@ -1010,3 +1047,9 @@ int oinfo( const string& args, UInterface& ui, int userparam )
}
// --------------------------------------------------------------------------------------
void errDoNotReolve( const std::string& oname )
{
if( verb )
cerr << oname << ": resolve failed.." << endl;
}
// --------------------------------------------------------------------------------------
......@@ -87,7 +87,7 @@ int main( int argc, char** argv )
LogServerTypes::Command cmd = LogServerTypes::cmdNOP;
int cmdonly = 0;
timeout_t tout = UniSetTimer::WaitUpTime;
timeout_t rdelay = 5000;
timeout_t rdelay = 8000;
string logfile("");
bool logtruncate = false;
......
......@@ -167,7 +167,6 @@ int main( int argc, char** argv )
la->printLogList(cout);
return 0;
#endif
LogServer ls(la);
ls.setMaxSessionCount(msess);
......@@ -214,9 +213,9 @@ int main( int argc, char** argv )
{
cerr << "(logserver): " << ex << endl;
}
catch(...)
catch( std::exception& ex)
{
cerr << "(logserver): catch(...)" << endl;
cerr << "(logserver): " << ex.what() << endl;
}
return 0;
......
......@@ -474,6 +474,9 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::preSysCommand( const SystemMessage*
mylog->logFile(fname.c_str(),true);
mylogany &lt;&lt; myname &lt;&lt; "(preSysCommand): ***************** mylog LOG ROTATE *****************" &lt;&lt; endl;
}
if( logserv &amp;&amp; !logserv_host.empty() &amp;&amp; logserv_port != 0 )
logserv-&gt;check(true);
}
break;
......@@ -493,7 +496,16 @@ UniSetTypes::SimpleInfo* <xsl:value-of select="$CLASSNAME"/>_SK::getInfo( CORBA:
ostringstream inf;
inf &lt;&lt; i->info &lt;&lt; endl;
inf &lt;&lt; "LogServer: " &lt;&lt; logserv_host &lt;&lt; ":" &lt;&lt; logserv_port &lt;&lt; endl;
if( logserv /* &amp;&amp; userparam &lt; 0 */ )
{
inf &lt;&lt; "LogServer: " &lt;&lt; logserv_host &lt;&lt; ":" &lt;&lt; logserv_port
&lt;&lt; ( logserv->isRunning() ? " [RUNNIG]" : " [FAILED]" ) &lt;&lt; endl;
inf &lt;&lt; " " &lt;&lt; logserv->getShortInfo() &lt;&lt; endl;
}
else
inf &lt;&lt; "LogServer: NONE" &lt;&lt; endl;
inf &lt;&lt; dumpIO() &lt;&lt; endl;
inf &lt;&lt; endl;
auto timers = getTimersList();
......@@ -658,8 +670,8 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::waitSM( int wait_msec, ObjectId _te
mycrit &lt;&lt; err.str() &lt;&lt; endl;
// terminate();
// abort();
raise(SIGTERM);
terminate();
// raise(SIGTERM);
std::terminate();
// throw SystemError(err.str());
}
......@@ -673,7 +685,8 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::waitSM( int wait_msec, ObjectId _te
mycrit &lt;&lt; err.str() &lt;&lt; endl;
// terminate();
// abort();
raise(SIGTERM);
//raise(SIGTERM);
std::terminate();
// throw SystemError(err.str());
}
}
......@@ -1121,6 +1134,7 @@ end_private(false)
vmonit(maxHeartBeat);
vmonit(activateTimeout);
vmonit(smReadyTimeout);
vmonit(smTestID);
// help надо выводить в конце, когда уже все переменные инициализированы по умолчанию
......@@ -1510,6 +1524,9 @@ askPause(uniset_conf()->getPIntProp(cnode,"askPause",2000))
if( smTestID == DefaultObjectId )
smTestID = getSMTestID();
vmonit(smTestID);
vmonit(smReadyTimeout);
activateTimeout = conf->getArgPInt("--" + argprefix + "activate-timeout", 20000);
int msec = conf->getArgPInt("--" + argprefix + "startup-timeout", 10000);
......
......@@ -42,6 +42,7 @@ TestGen::TestGen()
// -----------------------------------------------------------------------------
void TestGen::step()
{
#if 0
cout << "strval: " << strval(input2_s) << endl;
cout << "str: " << str(input2_s) << endl;
cout << "===========" << endl;
......@@ -53,7 +54,7 @@ void TestGen::step()
int_var++;
bool_var ^= true;
cout << vmon << endl;
#endif
// cout << vmon.pretty_str() << endl;
}
// -----------------------------------------------------------------------------
......
......@@ -2,8 +2,9 @@
ulimit -Sc 1000000
uniset2-start.sh -f ./test --name TestProc --confile test.xml --ulog-add-levels warn,crit \
--test-sm-ready-timeout 15000 --test-run-logserver --test-log-add-levels any $*
uniset2-start.sh -f ./test --name TestProc --confile test.xml --ulog-add-levels system,warn,crit \
--test-sm-ready-timeout 15000 --test-run-logserver --test-logserver-host 192.192.192.192
#--test-log-add-levels any $*
#info,warn,crit,system,level9 > 1.log
#--c-filter-field cfilter --c-filter-value test1 --s-filter-field io --s-filter-value 1
......
......@@ -16,7 +16,7 @@
Name: libuniset2
Version: 2.5
Release: alt13.M80P.14
Release: alt18.M80P.19
Summary: UniSet - library for building distributed industrial control systems
License: LGPL
......@@ -488,9 +488,40 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# ..
%changelog
* Tue Sep 13 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt13.M80P.14
* Tue Oct 11 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt18.M80P.19
- backport to ALTLinux p8 (by rpmbph script)
* Tue Oct 11 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt19
- Calibration: fixed bug in getValue(), refactoring
- correction after verification static analyzer
- LogServer: fixed bug "connection refuse"
* Sat Oct 08 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt18
- LogServer: fixed bug "do not close connection"
* Fri Sep 30 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt17
- ModbusMultiMaster: add new check connection strategy
- LogServer: minor fixes
* Tue Sep 27 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt16
- LogSession: add more logs
- codegen: add logserver information in getInfo()
* Tue Sep 20 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt15
- up build
* Tue Sep 20 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.4
- UTCPStream: check POCO_INVALID_SOCKET
* Mon Sep 19 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.3
- UTCPStream: shudown and close (for disconnect)
* Mon Sep 19 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.2
- (ModbusTCPMaster): added disconnect() function
* Mon Sep 19 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14.1
- (ModbusTCPMaster): added catch exceptions
* Mon Sep 12 2016 Pavel Vainerman <pv@altlinux.ru> 2.5-alt14
- up build
......
......@@ -206,4 +206,4 @@ UniSetTypes::Message::TheLastFieldOfTypeOfMessage.
Если в документации речь идёт о "процессе", как последовательности
действий во времени, это должно быть очевидно из контекста.
*/
*/
\ No newline at end of file
......@@ -61,4 +61,4 @@
При запуске программ используйте ключ "--help" для получения подробной информации
о настройке логов из командной строки
*/
*/
\ No newline at end of file
......@@ -49,5 +49,4 @@
возникнет необходимость, то можно будет вместо \a protected сделать их \a public.
\note Описание составлено на основе описания мьютексов из книги А.Цимбала "Технология CORBA для профессионалов".
*/
*/
\ No newline at end of file
......@@ -97,4 +97,4 @@
}
\endcode
*/
*/
\ No newline at end of file
......@@ -260,4 +260,4 @@ const UniSetTypes::ObjectInfo ObjectsMap[MAX_NUMOBJECTS] =
\section OMAP_secDynamicXML Динамическая карта объектов на основе XML-файла
\subsection OMAP_subDynamic_Create Создание динамической карты объектов
\subsection OMAP_subDynamic_Example Пример использования динамической карты объектов
*/
*/
\ No newline at end of file
......@@ -8,4 +8,4 @@
\section secDBServer Сервер БД
\sa \ref page_DBServer_MySQL
*/
*/
\ No newline at end of file
......@@ -304,4 +304,4 @@ Enum-ов (как в примере), дабы избежать в послед
...
}
\endcode
*/
*/
\ No newline at end of file
......@@ -34,4 +34,10 @@ d_DATA = html/*
# exampledir = $(docdir)/examples
# example_DATA = examples/*
pdf:
doxygen UniSetDox.cfg
subst 's|OT1|T2A|g' latex/doxygen.sty
subst 's|Times-Roman|Liberation Sans|g' latex/*
cd latex; make; cd -;
endif
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -384,9 +384,11 @@ void DBServer_MySQL::timerInfo( const UniSetTypes::TimerMessage* tm )
askTimer(DBServer_MySQL::ReconnectTimer, 0);
askTimer(DBServer_MySQL::PingTimer, PingTime);
}
connect_ok = false;
dbwarn << myname << "(timerInfo): DB no connection.." << endl;
else
{
connect_ok = false;
dbwarn << myname << "(timerInfo): DB no connection.." << endl;
}
}
else
initDBServer();
......
......@@ -220,10 +220,9 @@ void DBServer_PostgreSQL::flushInsertBuffer()
}
ibuf.erase(beg, end);
ibufSize -= delnum;
if( ibufSize < 0 )
ibufSize = 0;
// ibufSize - беззнаковое, так что надо аккуратно
ibufSize = (delnum < ibufSize) ? (ibufSize-delnum) : 0;
dbwarn << myname << "(flushInsertBuffer): overflow: clear data " << delnum << " records." << endl;
return;
......@@ -438,9 +437,11 @@ void DBServer_PostgreSQL::timerInfo( const UniSetTypes::TimerMessage* tm )
askTimer(DBServer_PostgreSQL::ReconnectTimer, 0);
askTimer(DBServer_PostgreSQL::PingTimer, PingTime);
}
connect_ok = false;
dbwarn << myname << "(timerInfo): DB no connection.." << endl;
else
{
connect_ok = false;
dbwarn << myname << "(timerInfo): DB no connection.." << endl;
}
}
else
initDBServer();
......
......@@ -110,7 +110,7 @@ class DBServer_PostgreSQL:
typedef std::queue<std::string> QueryBuffer;
QueryBuffer qbuf;
unsigned int qbufSize; // размер буфера сообщений.
size_t qbufSize; // размер буфера сообщений.
bool lastRemove = { false };
void flushBuffer();
......
......@@ -359,9 +359,11 @@ void DBServer_SQLite::timerInfo( const UniSetTypes::TimerMessage* tm )
askTimer(DBServer_SQLite::ReconnectTimer, 0);
askTimer(DBServer_SQLite::PingTimer, PingTime);
}
connect_ok = false;
dbwarn << myname << "(timerInfo): DB no connection.." << endl;
else
{
connect_ok = false;
dbwarn << myname << "(timerInfo): DB no connection.." << endl;
}
}
else
initDBServer();
......
......@@ -69,9 +69,9 @@ IOControl::IOControl(UniSetTypes::ObjectId id, UniSetTypes::ObjectId icID,
auto conf = uniset_conf();
string cname = conf->getArgParam("--" + prefix + "-confnode", myname);
cnode = conf->getNode(cname);
confnode = conf->getNode(cname);
if( cnode == NULL )
if( confnode == NULL )
throw SystemError("Not found conf-node " + cname + " for " + myname);
iolog = make_shared<DebugStream>();
......@@ -89,10 +89,10 @@ IOControl::IOControl(UniSetTypes::ObjectId id, UniSetTypes::ObjectId icID,
ioinfo << myname << "(init): numcards=" << numcards << endl;
UniXML::iterator it(cnode);
UniXML::iterator it(confnode);
logserv = make_shared<LogServer>(loga);
logserv->init( prefix + "-logserver", cnode );
logserv->init( prefix + "-logserver", confnode );
if( findArgParam("--" + prefix + "-run-logserver", conf->getArgc(), conf->getArgv()) != -1 )
{
......@@ -306,7 +306,7 @@ IOControl::~IOControl()
void IOControl::execute()
{
// set_signals(true);
UniXML::iterator it(cnode);
UniXML::iterator it(confnode);
waitSM(); // необходимо дождаться, чтобы нормально инициализировать итераторы
......@@ -1055,7 +1055,9 @@ void IOControl::check_testmode()
// если режим "выключено всё"
// то гасим все выходы
if( testmode == tmOffPoll )
if( testmode == tmOffPoll ||
testmode == tmConfigEnable ||
testmode == tmConfigDisable )
{
// выставляем безопасные состояния
for( auto& it : iomap )
......@@ -1602,17 +1604,15 @@ void IOControl::buildCardsList()
return;
}
//xmlNode* cnode = xml->findNode(mynode,"iocards","");
//xmlNode* extFindNode(xmlNode* node, int depth, int width, const std::string searchnode, const std::string name = "", bool top=true );
xmlNode* cnode = xml->extFindNode(mynode, 1, 1, "iocards", "");
xmlNode* cardsnode = xml->extFindNode(mynode, 1, 1, "iocards", "");
if( !cnode )
if( !cardsnode )
{
iowarn << myname << "(buildCardsList): Not found <iocards> for node=" << conf->getLocalNodeName() << "(" << conf->getLocalNode() << ")" << endl;
return;
}
UniXML::iterator it(cnode);
UniXML::iterator it(cardsnode);
if( !it.goChildren() )
{
......
......@@ -295,12 +295,12 @@ class IOControl:
enum TestModeID
{
tmNone = 0, /*!< тестовый режим отключён */
tmOffPoll = 1, /*!< отключить опрос */
tmConfigEnable = 2, /*!< специальный режим, в соответствии с настройкой 'enable_testmode' */
tmNone = 0, /*!< тестовый режим отключён */
tmOffPoll = 1, /*!< отключить опрос */
tmConfigEnable = 2, /*!< специальный режим, в соответствии с настройкой 'enable_testmode' */
tmConfigDisable = 3, /*!< специальный режим, в соответствии с настройкой 'disable_testmode' */
tmOnlyInputs = 4, /*!< включены только входы */
tmOnlyOutputs = 5 /*!< включены только выходы */
tmOnlyInputs = 4, /*!< включены только входы */
tmOnlyOutputs = 5 /*!< включены только выходы */
};
void execute();
......@@ -335,7 +335,7 @@ class IOControl:
void waitSM();
xmlNode* cnode = { 0 }; /*!< xml-узел в настроечном файле */
xmlNode* confnode = { 0 }; /*!< xml-узел в настроечном файле */
int polltime = { 150 }; /*!< переодичность обновления данных (опроса карт в/в), [мсек] */
CardList cards; /*!< список карт - массив созданных ComediInterface */
......
......@@ -72,7 +72,6 @@ int subdev = 0;
int chan = 0;
int range = 0;
int aref = AREF_GROUND;
bool go = true;
static struct option longopts[] =
{
......
......@@ -31,6 +31,7 @@
- \ref sec_MBTCPM_Conf
- \ref sec_MBTCPM_ConfList
- \ref sec_MBTCPM_ExchangeMode
- \ref sec_MBTCPM_CheckConnection
\section sec_MBTCPM_Comm Общее описание ModbusTCPMultiMaster
Класс реализует процесс обмена (опрос/запись) с RTU-устройствами,
......@@ -85,6 +86,9 @@
- \b respond_invert - инвертировать датчик связи (DI)
- \b force [1,0] - "1" - обновлять значение датчика связи в SM принудительно на каждом цикле проверки ("0" - только по изменению).
- \b timeout - таймаут на определение отсутсвия связи для данного канала. По умолчанию берётся глобальный.
- \b checkFunc - Номер функции для проверки соединения
- \b checkAddr - Адрес устройства для проверки соединения
- \b checkReg - Регистр для проверки соединения
\par Параметры запуска
......@@ -143,6 +147,11 @@
\b --xxx-activate-timeout msec . По умолчанию 2000. - время ожидания готовности SharedMemory к работе.
\b --xxx-check-func [1,2,3,4] - Номер функции для проверки соединения
\b --xxx-check-addr [1..255 ] - Адрес устройства для проверки соединения
\b --xxx-check-reg [1..65535] - Регистр для проверки соединения
\b --xxx-check-init-from-regmap - Взять адрес, функцию и регистр для проверки связи из списка опроса
\section sec_MBTCPM_ConfList Конфигурирование списка регистров для ModbusTCP master
Конфигурационные параметры задаются в секции <sensors> конфигурационного файла.
Список обрабатываемых регистров задаётся при помощи двух параметров командной строки
......@@ -207,8 +216,6 @@
регистры в устройство писатся не будут. Чтобы отключить это поведение, можно указать параметр
- \b tcp_sm_initOK - [0|1] Игнорировать начальную инициализацию из SM (сразу писать в устройство)
При этом будет записывыться значение "default".
\warning Регистр должен быть уникальным. И может повторятся только если указан параметр \a nbit или \a nbyte.
......@@ -228,10 +235,43 @@
Режимы переключаются при помощи датчика, который можно задать либо аргументом командной строки
\b --prefix-exchange-mode-id либо в конф. файле параметром \b exchangeModeID="". Константы определяющие режимы объявлены в MBTCPMultiMaster::ExchangeMode.
\section sec_MBTCPM_CheckConnection Проверка соединения
Для контроля состояния связи по "резервным" каналам создаётся специальный поток (check_thread), в котором
происходит периодическая проверка связи по всем "пассивным"(резервным) в данный момент каналам. Это используется
как для общей диагностики в системе, так и при выборе на какой канал переключаться в случае пропажи связи в основном канале.
Т.е. будет выбран ближайший приоритетный канал у которого выставлен признак что есть связь.
Период проверки связи по "резервным" каналам задаётся при помощи --prefix-checktime или параметром checktime="" в конфигурационном файле.
В MBTCPMultiMaster реализовано два механизма проверки связи.
- По умолчанию используется простая установка соединения и тут же его разрыв. Т.е. данные никакие не посылаются,
но проверяется что host и port доступны для подключения.
- Второй способ: это проверка соединения с посылкой modbus-запроса. Для этого имеется два способа
указать адрес устройства, регистр и функция опроса для проверки.
Либо в секции <GateList> для каждого канала можно указать:
- адрес устройства \b checkAddr=""
- функцию проверки \b checkFunc="" - функция может быть только [01,02,03,04] (т.е. функции чтения).
- регистр \b checkReg
Либо в командной строке \b задать параметры --prefix-check-addr, --prefix-check-func, --prefix-check-reg,
которые будут одинаковыми для \b ВСЕХ \b КАНАЛОВ.
Помимо этого если указать в командной строке аргумент --prefix-check-init-from-regmap, то для тестирования
соединения будет взят первый попавшийся регистр из списка обмена.
\warning Способ проверки при помощи "modbus-запроса" имеет ряд проблем: Если фактически производится
обмен с несколькими устройствами (несколько mbaddr) через TCP-шлюз, то может быть "ложное" срабатвание,
т.к. фактически состояние канала будет определяться только под связи с каким-то одним конкретным устройством.
И получается, что если обмен ведётся например с тремя устройствами, но
проверка канала происходит только по связи с первым, то если оно перестанет отвечать, это будет считаться
сбоем всего канала и этот канал будет исключён из обмена (!). Если ведётся обмен только с одним устройством,
такой проблеммы не возникает.
Но к плюсам данного способа проверки связи ("modbus-запросом") является то, что соедиенение поддерживается
постоянным, в отличие от "первого способа" при котором оно создаётся и сразу рвётся и если проверка
настроена достаточно часто ( < TIME_WAIT для сокетов), то при длительной работе могут закончится дескрипторы
на создание сокетов.
*/
// -----------------------------------------------------------------------------
/*!
\par Реализация Modbus TCP Multi Master для обмена с многими ModbusRTU устройствами
\par Реализация Modbus TCP MultiMaster для обмена с многими ModbusRTU устройствами
через один modbus tcp шлюз, доступный по нескольким ip-адресам.
\par Чтобы не зависеть от таймаутов TCP соединений, которые могут неопределённо зависать
......@@ -263,6 +303,7 @@ class MBTCPMultiMaster:
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) override;
virtual void sigterm( int signo ) override;
virtual bool deactivateObject() override;
void initCheckConnectionParameters();
void poll_thread();
void check_thread();
......@@ -288,6 +329,11 @@ class MBTCPMultiMaster:
std::shared_ptr<ModbusTCPMaster> mbtcp;
int priority;
// параметры для проверки соединения..
ModbusRTU::SlaveFunctionCode checkFunc = { ModbusRTU::fnUnknown };
ModbusRTU::ModbusAddr checkAddr = { 0x00 };
ModbusRTU::ModbusData checkReg = { 0 };
bool respond;
UniSetTypes::ObjectId respond_id;
IOController::IOStateList::iterator respond_it;
......@@ -297,18 +343,14 @@ class MBTCPMultiMaster:
DelayTimer respondDelay;
timeout_t channel_timeout = { 0 };
inline bool operator < ( const MBSlaveInfo& mbs ) const
inline bool operator < ( const MBSlaveInfo& mbs ) const noexcept
{
return priority < mbs.priority;
}
bool init( std::shared_ptr<DebugStream>& mblog );
bool check() const;
inline void setUse( bool st )
{
respond_init = !( st && !use );
use = st;
}
bool check();
void setUse( bool st );
timeout_t recv_timeout;
timeout_t aftersend_pause;
......@@ -323,9 +365,11 @@ class MBTCPMultiMaster:
PassiveTimer ptIgnoreTimeout;
const std::string getShortInfo() const;
std::mutex mutInit;
};
typedef std::list<MBSlaveInfo> MBGateList;
typedef std::list<std::shared_ptr<MBSlaveInfo>> MBGateList;
MBGateList mblist;
MBGateList::reverse_iterator mbi;
......
......@@ -4,7 +4,7 @@ MBPARAM=
for N in `seq 1 100`; do
MBPARAM="$MBPARAM --mbtcp${N}-name MBTCP${N} --mbtcp${N}-confnode MBPerfTestMaster --mbtcp${N}-filter-field mbperf
--mbtcp${N}-filter-value $N --mbtcp${N}-persistent-connection 1 --mbtcp${N}-log-add-levels crit,warn"
--mbtcp${N}-filter-value $N --mbtcp${N}-persistent-connection 1 --mbtcp${N}-check-init-from-regmap --mbtcp${N}-log-add-levels warn,crit"
done
#echo "$MBPARAM"
......
......@@ -14,6 +14,10 @@
--mbtcp-log-add-levels level4,warn,crit \
--mbtcp-persistent-connection 1 \
--mbtcp-run-logserver \
--mbtcpX-check-init-from-regmap \
--mbtcpX-check-addr 1 \
--mbtcpX-check-reg 66 \
--mbtcpX-check-func 1 \
$*
#--dlog-add-levels info,crit,warn,level4,level3,level9 \
......
......@@ -124,6 +124,47 @@ TEST_CASE("MBTCPMaster: reconnect", "[modbus][mbmaster][mbtcpmaster]")
REQUIRE_FALSE(mb.isConnection());
}
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: forceDisconnect", "[modbus][mbmaster][mbtcpmaster][forceDisconnect]")
{
InitTest();
ModbusTCPMaster mb;
mb.setTimeout(500);
for( size_t i=0; i<1000; i++ )
{
// подключение к несуществующему адресу
REQUIRE_FALSE(mb.connect(iaddr, 2048));
try
{
mb.read03(slaveADDR,10,1);
}
catch(...){}
REQUIRE_FALSE(mb.isConnection());
mb.forceDisconnect();
}
}
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: disconnect", "[modbus][mbmaster][mbtcpmaster][disconnect]")
{
InitTest();
ModbusTCPMaster mb;
mb.setTimeout(500);
mb.setForceDisconnect(true);
for( size_t i=0; i<1000; i++ )
{
// подключение к несуществующему адресу
REQUIRE_FALSE(mb.connect(iaddr, 2048));
try
{
mb.read03(slaveADDR,10,1);
}
catch(...){}
REQUIRE_FALSE(mb.isConnection());
mb.disconnect();
}
}
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: 0x01 (read coil status)", "[modbus][0x01][mbmaster][mbtcpmaster]")
{
InitTest();
......
......@@ -337,7 +337,6 @@ class MBSlave:
VTypes::VType vtype; /*!< type of value */
size_t wnum; /*!< номер слова (для типов с размеров больше 2х байт */
size_t nbyte; /*!< номер байта, который надо "сохранить" из "пришедщего в запросе" слова. [1-2] */
bool rawdata; /*!< флаг, что в SM просто сохраняются 4-байта (актуально для типа F4)*/
std::shared_ptr<BitRegProperty> bitreg; /*!< указатель, как признак является ли данный регистр "сборным" из битовых */
ModbusRTU::RegID regID;
......@@ -347,7 +346,6 @@ class MBSlave:
vtype(VTypes::vtUnknown),
wnum(0),
nbyte(0),
rawdata(false),
regID(0)
{}
......
......@@ -54,6 +54,17 @@ RRDServer::RRDServer(UniSetTypes::ObjectId objId, xmlNode* cnode, UniSetTypes::O
for( ; it1.getCurrent(); it1++, ++tmID )
initRRD(it1, tmID);
if( smTestID == DefaultObjectId && !rrdlist.empty() )
{
// берём первый датчик из списка
const auto& lst = rrdlist.begin()->dslist;
if( !lst.empty() )
{
const auto& dsi = *(lst.begin());
smTestID = dsi->sid;
}
}
}
// -----------------------------------------------------------------------------
RRDServer::~RRDServer()
......@@ -268,6 +279,8 @@ void RRDServer::help_print( int argc, const char* const* argv )
cout << " set-levels ... " << endl;
cout << " logfile filanme " << endl;
cout << " no-debug " << endl;
cout << " Base oprtions: " << endl;
// cout << UObject_SK::help() << endl;
cout << " LogServer: " << endl;
cout << "--prefix-run-logserver - run logserver. Default: localhost:id" << endl;
cout << "--prefix-logserver-host ip - listen ip. Default: localhost" << endl;
......@@ -315,6 +328,9 @@ void RRDServer::askSensors( UniversalIO::UIOCommand cmd )
{
UObject_SK::askSensors(cmd);
// прежде чем заказывать датчики, надо убедиться что SM доступна
waitSM(smReadyTimeout);
for( auto& it : rrdlist )
{
for( auto& s : it.dsmap )
......
......@@ -69,8 +69,6 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std:
msecPulsar(0),
confnode(0)
{
mutex_start.setName(myname + "_mutex_start");
auto conf = uniset_conf();
string cname(confname);
......@@ -155,7 +153,7 @@ SharedMemory::SharedMemory( ObjectId id, const std::string& datafile, const std:
evntPause = conf->getArgPInt("--e-startup-pause", 5000);
activateTimeout = conf->getArgPInt("--activate-timeout", 30000);
activateTimeout = conf->getArgPInt("--activate-timeout", 60000);
sidPulsar = DefaultObjectId;
string p = conf->getArgParam("--pulsar-id", it.getProp("pulsar_id"));
......@@ -197,17 +195,21 @@ SharedMemory::~SharedMemory()
void SharedMemory::timerInfo( const TimerMessage* tm )
{
if( tm->id == tmHeartBeatCheck )
{
checkHeartBeat();
}
else if( tm->id == tmEvent )
{
workready = 1;
workready = true;
// рассылаем уведомление, о том, чтобы стартанули
SystemMessage sm1(SystemMessage::WatchDog);
sendEvent(sm1);
askTimer(tm->id, 0);
}
else if( tm->id == tmHistory )
{
saveToHistory();
}
else if( tm->id == tmPulsar )
{
if( sidPulsar != DefaultObjectId )
......@@ -241,11 +243,14 @@ void SharedMemory::sysCommand( const SystemMessage* sm )
}
if( !activated )
smcrit << myname << "(sysCommand): ************* don`t activate?! ************" << endl;
{
smcrit << myname << "(sysCommand): Don`t activate! TERMINATE.." << endl;
std::terminate();
}
// подождать пока пройдёт инициализация
// см. activateObject()
UniSetTypes::uniset_rwmutex_rlock l(mutex_start);
std::unique_lock<std::mutex> lock(mutexStart);
askTimer(tmHeartBeatCheck, heartbeatCheckTime);
askTimer(tmEvent, evntPause, 1);
......@@ -294,7 +299,7 @@ bool SharedMemory::activateObject()
{
activated = false;
UniSetTypes::uniset_rwmutex_wrlock l(mutex_start);
std::unique_lock<std::mutex> lock(mutexStart);
res = IONotifyController::activateObject();
// инициализируем указатели
......@@ -328,6 +333,7 @@ bool SharedMemory::activateObject()
}
cout << myname << ": ********** activate: " << pt.getCurrent() << " msec " << endl;
sminfo << myname << ": ********** activate: " << pt.getCurrent() << " msec " << endl;
return res;
}
// ------------------------------------------------------------------------------------------
......
......@@ -201,7 +201,7 @@
<item default="1" id="104104" iotype="DI" name="_41_04_S">
<MessagesList>
<msg mtype="1" text="КСЭС: отключился ввод\вывод" value="0"/>
<msg mtype="1" text="КСЭС: отключился ввод/вывод" value="0"/>
</MessagesList>
</item>
\endcode
......@@ -417,7 +417,7 @@ class SharedMemory:
void buildEventList( xmlNode* cnode );
void readEventList( const std::string& oname );
UniSetTypes::uniset_rwmutex mutex_start;
std::mutex mutexStart;
class HeartBeatInfo
{
......
......@@ -99,9 +99,6 @@ int main( int argc, const char** argv )
ThreadCreator<IOControl>* io_thr = new ThreadCreator<IOControl>(ic.get(), &IOControl::execute);
if( io_thr == NULL )
return 1;
act->add(ic);
lst_iothr.push_back( io_thr );
}
......
......@@ -39,12 +39,12 @@ UNetSender::UNetSender(const std::string& _host, const int _port, const std::sha
sendpause(150),
packsendpause(5),
activated(false),
items(100),
packetnum(1),
lastcrc(0),
maxAData(maxACount),
maxDData(maxDCount)
{
items.reserve(100);
{
ostringstream s;
......
......@@ -77,8 +77,8 @@ class Calibration
{
public:
Calibration();
Calibration( const std::string& name, const std::string& confile = "calibration.xml" );
Calibration( xmlNode* node );
Calibration( const std::string& name, const std::string& confile = "calibration.xml", size_t reserv=50 );
Calibration( xmlNode* node, size_t reserv=50 );
~Calibration();
/*! Тип для хранения значения */
......@@ -96,26 +96,26 @@ class Calibration
\param crop_raw - обрезать переданное значение по крайним точкам
\return Возвращает калиброванное или outOfRange
*/
long getValue( long raw, bool crop_raw = false );
long getValue( const long raw, bool crop_raw = false );
/*! Возвращает минимальное значение 'x' встретившееся в диаграмме */
inline long getMinValue()
inline long getMinValue() const noexcept
{
return minVal;
}
/*! Возвращает максимальное значение 'x' втретившееся в диаграмме */
inline long getMaxValue()
inline long getMaxValue() const noexcept
{
return maxVal;
}
/*! Возвращает крайнее левое значение 'x' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getLeftValue()
inline long getLeftValue() const noexcept
{
return leftVal;
}
/*! Возвращает крайнее правое значение 'x' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getRightValue()
inline long getRightValue() const noexcept
{
return rightVal;
}
......@@ -127,26 +127,26 @@ class Calibration
Если range=false, то может быть возвращено значение outOfRange.
*/
long getRawValue( long cal, bool range = false );
long getRawValue( const long cal, bool range = false );
/*! Возвращает минимальное значение 'y' встретившееся в диаграмме */
inline long getMinRaw()
inline long getMinRaw() const noexcept
{
return minRaw;
}
/*! Возвращает максимальное значение 'y' встретившееся в диаграмме */
inline long getMaxRaw()
inline long getMaxRaw() const noexcept
{
return maxRaw;
}
/*! Возвращает крайнее левое значение 'y' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getLeftRaw()
inline long getLeftRaw() const noexcept
{
return leftRaw;
}
/*! Возвращает крайнее правое значение 'y' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getRightRaw()
inline long getRightRaw() const noexcept
{
return rightRaw;
}
......@@ -166,14 +166,15 @@ class Calibration
return lround(val);
}
void setCacheSize( unsigned int sz );
inline unsigned int getCacheSize()
void setCacheSize( size_t sz );
inline size_t getCacheSize() const
{
return cache.size();
}
void setCacheResortCycle( unsigned int n );
inline unsigned int getCacheResotrCycle()
void setCacheResortCycle( size_t n );
inline size_t getCacheResotrCycle() const noexcept
{
return numCacheResort;
}
......@@ -204,64 +205,64 @@ class Calibration
class Part
{
public:
Part();
Part( const Point& pleft, const Point& pright );
Part() noexcept;
Part( const Point& pleft, const Point& pright ) noexcept;
~Part() {};
/*! находится ли точка на данном участке */
bool check( const Point& p ) const;
/*! находится ли точка на данном участке */
bool check( const Point& p ) const noexcept;
/*! находится ли точка на данном участке по X */
bool checkX( const TypeOfValue& x ) const;
/*! находится ли точка на данном участке по X */
bool checkX( const TypeOfValue& x ) const noexcept;
/*! находится ли точка на данном участке по Y */
bool checkY( const TypeOfValue& y ) const;
bool checkY( const TypeOfValue& y ) const noexcept;
// функции могут вернуть OutOfRange
TypeOfValue getY( const TypeOfValue& x ) const; /*!< получить значение Y */
TypeOfValue getX( const TypeOfValue& y ) const; /*!< получить значение X */
TypeOfValue getY( const TypeOfValue& x ) const noexcept; /*!< получить значение Y */
TypeOfValue getX( const TypeOfValue& y ) const noexcept; /*!< получить значение X */
TypeOfValue calcY( const TypeOfValue& x ) const; /*!< расчитать значение для x */
TypeOfValue calcX( const TypeOfValue& y ) const; /*!< расчитать значение для y */
TypeOfValue calcY( const TypeOfValue& x ) const noexcept; /*!< расчитать значение для x */
TypeOfValue calcX( const TypeOfValue& y ) const noexcept; /*!< расчитать значение для y */
inline bool operator < ( const Part& p ) const
inline bool operator < ( const Part& p ) const noexcept
{
return (p_right < p.p_right);
}
inline Point leftPoint() const
inline Point leftPoint() const noexcept
{
return p_left;
}
inline Point rightPoint() const
inline Point rightPoint() const noexcept
{
return p_right;
}
inline TypeOfValue getK() const
inline TypeOfValue getK() const noexcept
{
return k; /*!< получить коэффициент наклона */
}
inline TypeOfValue left_x() const
inline TypeOfValue left_x() const noexcept
{
return p_left.x;
}
inline TypeOfValue left_y() const
inline TypeOfValue left_y() const noexcept
{
return p_left.y;
}
inline TypeOfValue right_x() const
inline TypeOfValue right_x() const noexcept
{
return p_right.x;
}
inline TypeOfValue right_y() const
inline TypeOfValue right_y() const noexcept
{
return p_right.y;
}
protected:
Point p_left; /*!< левый предел участка */
Point p_right; /*!< правый предел участка */
TypeOfValue k; /*!< коэффициент наклона */
Point p_left; /*!< левый предел участка */
Point p_right; /*!< правый предел участка */
TypeOfValue k; /*!< коэффициент наклона */
};
// список надо отсортировать по x!
......@@ -283,19 +284,19 @@ class Calibration
std::string myname;
// Cache
unsigned int szCache;
size_t szCache;
struct CacheInfo
{
CacheInfo(): val(0), raw(outOfRange), cnt(0) {}
CacheInfo( const long r, const long v ): val(v), raw(r), cnt(0) {}
CacheInfo() noexcept: val(0), raw(outOfRange), cnt(0) {}
CacheInfo( const long r, const long v ) noexcept: val(v), raw(r), cnt(0) {}
long val;
long raw;
unsigned long cnt; // счётчик обращений
size_t cnt; // счётчик обращений
// сортируем в порядке убывания(!) обращений
// т.е. наиболее часто используемые (впереди)
inline bool operator<( const CacheInfo& r ) const
inline bool operator<( const CacheInfo& r ) const noexcept
{
if( r.raw == outOfRange )
return true;
......@@ -310,8 +311,8 @@ class Calibration
typedef std::deque<CacheInfo> ValueCache;
ValueCache cache;
unsigned long numCacheResort; // количество обращений, при которых происходит перестроение (сортировка) кэша..
unsigned long numCallToCache; // текущий счётчик обращений к кэшу
size_t numCacheResort; // количество обращений, при которых происходит перестроение (сортировка) кэша..
size_t numCallToCache; // текущий счётчик обращений к кэшу
};
// -----------------------------------------------------------------------------
#endif // Calibration_H_
......
......@@ -717,8 +717,8 @@ namespace MTR
return val;
}
unsigned short val;
float fval;
unsigned short val = { 0 };
float fval = { 0.0 };
};
std::ostream& operator<<(std::ostream& os, T16& t );
// --------------------------------------------------------------------------
......@@ -765,8 +765,8 @@ namespace MTR
return val;
}
signed short val;
float fval;
signed short val = { 0 };
float fval = { 0 };
};
std::ostream& operator<<(std::ostream& os, T17& t );
// --------------------------------------------------------------------------
......
......@@ -114,7 +114,7 @@ namespace VTypes
// ------------------------------------------
// конструкторы на разные случаи...
F2r() noexcept {}
F2r() noexcept { raw_backorder.val = 0; }
F2r( const float& f ) noexcept: F2(f)
{
......@@ -383,7 +383,7 @@ namespace VTypes
public I2
{
public:
I2r() noexcept {}
I2r() noexcept { raw_backorder.val = 0; }
I2r( const int v ) noexcept: I2(v)
{
......@@ -457,7 +457,7 @@ namespace VTypes
public U2
{
public:
U2r() noexcept {}
U2r() noexcept { raw_backorder.val = 0; }
U2r( int v ) noexcept: U2(v)
{
......
......@@ -29,23 +29,19 @@ using namespace UniSetTypes;
const Calibration::TypeOfValue Calibration::ValueOutOfRange = std::numeric_limits<Calibration::TypeOfValue>::max();
const long Calibration::outOfRange = std::numeric_limits<long>::max();
// ----------------------------------------------------------------------------
Calibration::Part::Part():
Calibration::Part::Part() noexcept:
k(0)
{
}
Calibration::Part::Part( const Point& pleft, const Point& pright ):
Calibration::Part::Part( const Point& pleft, const Point& pright ) noexcept:
p_left(pleft),
p_right(pright),
k(0)
{
if( p_right.x < p_left.x )
{
Point t(p_right);
p_right = p_left;
p_left = t;
}
std::swap(p_right,p_left);
// вычисление коэффициента наклона (один раз в конструкторе)
// k = (y2-y1)/(x2-x1)
......@@ -55,29 +51,28 @@ Calibration::Part::Part( const Point& pleft, const Point& pright ):
k = ( p_right.y - p_left.y ) / ( p_right.x - p_left.x );
}
// ----------------------------------------------------------------------------
bool Calibration::Part::check( const Point& p ) const
bool Calibration::Part::check( const Point& p ) const noexcept
{
return ( checkX(p.x) && checkY(p.y) );
}
bool Calibration::Part::checkX( const TypeOfValue& x ) const
// ----------------------------------------------------------------------------
bool Calibration::Part::checkX( const TypeOfValue& x ) const noexcept
{
if( x < p_left.x || x > p_right.x )
return false;
return true;
}
bool Calibration::Part::checkY( const TypeOfValue& y ) const
// ----------------------------------------------------------------------------
bool Calibration::Part::checkY( const TypeOfValue& y ) const noexcept
{
if( y < p_left.y || y > p_right.y )
return false;
return true;
}
// ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::getY( const TypeOfValue& x ) const
Calibration::TypeOfValue Calibration::Part::getY( const TypeOfValue& x ) const noexcept
{
if( !checkX(x) )
return Calibration::ValueOutOfRange;
......@@ -91,7 +86,7 @@ Calibration::TypeOfValue Calibration::Part::getY( const TypeOfValue& x ) const
return calcY(x);
}
// ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::getX( const TypeOfValue& y ) const
Calibration::TypeOfValue Calibration::Part::getX( const TypeOfValue& y ) const noexcept
{
if( !checkY(y) )
return Calibration::ValueOutOfRange;
......@@ -105,13 +100,13 @@ Calibration::TypeOfValue Calibration::Part::getX( const TypeOfValue& y ) const
return calcX(y);
}
// ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::calcY( const TypeOfValue& x ) const
Calibration::TypeOfValue Calibration::Part::calcY( const TypeOfValue& x ) const noexcept
{
// y = y0 + kx
return k * (x - p_left.x) + p_left.y;
}
// ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const
Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const noexcept
{
// x = (y - y0) / k
if( k == 0 )
......@@ -123,7 +118,6 @@ Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const
Calibration::Calibration():
minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0),
pvec(50),
myname(""),
szCache(5),
numCacheResort(20),
......@@ -134,25 +128,26 @@ Calibration::Calibration():
// ----------------------------------------------------------------------------
Calibration::Calibration( const string& name, const string& confile ):
Calibration::Calibration( const string& name, const string& confile, size_t reserv ):
minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0),
pvec(50),
myname(name),
szCache(5),
numCacheResort(20),
numCallToCache(5)
{
pvec.reserve(reserv);
cache.assign(szCache, CacheInfo());
build(name, confile, 0);
}
// ----------------------------------------------------------------------------
Calibration::Calibration( xmlNode* node ):
minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0), pvec(100),
Calibration::Calibration(xmlNode* node , size_t reserv ):
minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0),
szCache(5),
numCacheResort(20),
numCallToCache(5)
{
pvec.reserve(reserv);
cache.assign(szCache, CacheInfo());
UniXML::iterator it(node);
myname = it.getProp("name");
......@@ -199,14 +194,13 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
}
bool prev = false;
Point prev_point(0, 0);
unsigned int i = 0;
Point prev_point;
for(; it; it.goNext())
for(; it; it++ )
{
Point p(prev_point);
p.x = atof(it.getProp("x").c_str());
p.y = atof(it.getProp("y").c_str());
p.x = std::atof(it.getProp("x").c_str());
p.y = std::atof(it.getProp("y").c_str());
if( p.x == 0 || p.y == 0 )
{
......@@ -225,36 +219,28 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
minVal = p.y;
if( prev )
{
Part pt(prev_point, p);
pvec[i++] = pt;
if( i >= pvec.size() )
pvec.resize(pvec.size() + 20);
}
pvec.emplace_back(prev_point, p);
else
prev = true;
prev_point = p;
}
pvec.resize(i); // приводим размер к фактическому..
pvec.shrink_to_fit();
std::sort(pvec.begin(), pvec.end());
auto beg = pvec.begin();
auto end = pvec.end();
if( pvec.size() > 0 )
if( !pvec.empty() )
{
auto beg = pvec.begin();
auto end = --pvec.end();
leftRaw = beg->left_x();
leftVal = beg->left_y();
--end;
rightRaw = end->right_x();
rightVal = end->right_y();
}
}
catch( const Exception& ex )
catch( const UniSetTypes::Exception& ex )
{
dcrit << myname << "(Calibration::build): Failed open " << confile << endl;
throw;
......@@ -262,7 +248,7 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
}
// ----------------------------------------------------------------------------
// рекурсивная функция поиска методом "половинного деления"
static Calibration::PartsVec::iterator find_range( long raw, Calibration::PartsVec::iterator beg,
static Calibration::PartsVec::iterator find_range( const long raw, Calibration::PartsVec::iterator beg,
Calibration::PartsVec::iterator end )
{
if( beg->checkX(raw) )
......@@ -282,7 +268,7 @@ static Calibration::PartsVec::iterator find_range( long raw, Calibration::PartsV
return it;
}
// ----------------------------------------------------------------------------
long Calibration::getValue( long raw, bool crop_raw )
long Calibration::getValue( const long raw, bool crop_raw )
{
// если x левее первого отрезка то берём первую точку...
if( raw < leftRaw )
......@@ -312,7 +298,7 @@ long Calibration::getValue( long raw, bool crop_raw )
}
}
auto fit = find_range(raw, pvec.begin(), pvec.end());
auto fit = find_range(raw, pvec.begin(), --pvec.end() );
if( fit == pvec.end() )
{
......@@ -338,13 +324,13 @@ long Calibration::getValue( long raw, bool crop_raw )
return outOfRange;
}
// ----------------------------------------------------------------------------
void Calibration::setCacheResortCycle( unsigned int n )
void Calibration::setCacheResortCycle( size_t n )
{
numCacheResort = n;
numCallToCache = n;
}
// ----------------------------------------------------------------------------
void Calibration::setCacheSize( unsigned int sz )
void Calibration::setCacheSize( size_t sz )
{
sort(cache.begin(), cache.end()); // в порядке уменьшения обращений (см. CacheInfo::operator< )
cache.resize(sz);
......@@ -358,7 +344,7 @@ void Calibration::insertToCache( const long raw, const long val )
sort(cache.begin(), cache.end()); // пересортируем в порядке уменьшения обращений (см. CacheInfo::operator< )
}
// ----------------------------------------------------------------------------
long Calibration::getRawValue( long cal, bool range )
long Calibration::getRawValue( const long cal, bool range )
{
for( auto& it : pvec )
{
......
......@@ -33,7 +33,6 @@ DigitalFilter::DigitalFilter( unsigned int bufsize, double T, double lsq,
S(0),
tmr(UniSetTimer::WaitUpTime),
maxsize(bufsize),
mvec(bufsize),
mvec_sorted(false),
w(bufsize),
lsparam(lsq),
......
......@@ -192,7 +192,9 @@ bool IOBase::check_front( bool val )
void IOBase::processingAsAI( IOBase* it, long val, const std::shared_ptr<SMInterface>& shm, bool force )
{
if( it->stype == UniversalIO::DI || it->stype == UniversalIO::DO )
val = (val ? 1.0 : 0.0);
{
val = (val ? 1 : 0);
}
else
{
// проверка на обрыв
......@@ -270,7 +272,7 @@ void IOBase::processingFasAI( IOBase* it, float fval, const std::shared_ptr<SMIn
long val = lroundf(fval);
if( it->stype == UniversalIO::DI || it->stype == UniversalIO::DO )
val = (fval != 0 ? 1.0 : 0.0);
val = (fval != 0 ? 1 : 0);
else
{
if( it->rawdata )
......
......@@ -74,7 +74,7 @@ using namespace UniSetTypes;
{ \
uwarn << "(" << __STRING(fname) << "): " << ex.err << endl; \
} \
catch( const Exception& ex ) \
catch( const UniSetTypes::Exception& ex ) \
{ \
uwarn << "(" << __STRING(fname) << "): " << ex << endl; \
} \
......
......@@ -53,8 +53,8 @@ void TestProc::sysCommand( const UniSetTypes::SystemMessage* sm )
// -----------------------------------------------------------------------------
string TestProc::getMonitInfo()
{
int* p = 0;
(*p) = 10;
// int* p = 0;
// (*p) = 10;
return "";
}
......
......@@ -17,7 +17,7 @@
#ifndef LogServer_H_
#define LogServer_H_
// -------------------------------------------------------------------------
#include <list>
#include <vector>
#include <string>
#include <memory>
#include <unordered_map>
......@@ -87,8 +87,8 @@ class LogServer:
{
public:
LogServer( std::shared_ptr<DebugStream> log ) noexcept;
LogServer( std::shared_ptr<LogAgregator> log ) noexcept;
LogServer( std::shared_ptr<DebugStream> log );
LogServer( std::shared_ptr<LogAgregator> log );
virtual ~LogServer() noexcept;
inline void setCmdTimeout( timeout_t msec ) noexcept
......@@ -113,6 +113,8 @@ class LogServer:
return isrunning;
}
bool check( bool restart_if_fail = true );
void init( const std::string& prefix, xmlNode* cnode = 0 );
static std::string help_print( const std::string& prefix );
......@@ -120,7 +122,7 @@ class LogServer:
std::string getShortInfo();
protected:
LogServer() noexcept;
LogServer();
virtual void evprepare( const ev::loop_ref& loop ) override;
virtual void evfinish( const ev::loop_ref& loop ) override;
......@@ -136,16 +138,16 @@ class LogServer:
std::string onCommand( LogSession* s, LogServerTypes::Command cmd, const std::string& logname );
private:
typedef std::list< std::shared_ptr<LogSession> > SessionList;
SessionList slist;
size_t scount = { 0 };
UniSetTypes::uniset_rwmutex mutSList;
timeout_t timeout = { UniSetTimer::WaitUpTime };
timeout_t cmdTimeout = { 2000 };
Debug::type sessLogLevel = { Debug::NONE };
size_t sessMaxCount = { 10 };
typedef std::vector< std::shared_ptr<LogSession> > SessionList;
SessionList slist;
UniSetTypes::uniset_rwmutex mutSList;
DebugStream mylog;
ev::io io;
......
......@@ -77,6 +77,8 @@ class LogSession
std::string getShortInfo() noexcept;
std::string name() const noexcept;
protected:
// LogSession( ost::TCPSocket& server );
......
......@@ -180,8 +180,6 @@ class NCRestorer_XML:
std::string s_filterField;
std::string s_filterValue;
std::string c_filterField;
std::string c_filterValue;
std::string t_filterField;
std::string t_filterValue;
......
......@@ -93,7 +93,7 @@ class ThreadCreator:
typedef void(ThreadMaster::* Action)(void);
ThreadCreator( ThreadMaster* m, Action a );
~ThreadCreator();
virtual ~ThreadCreator();
inline Poco::Thread::TID getTID() const
{
......
......@@ -44,6 +44,7 @@ class UTCPStream:
bool isSetLinger() const;
void forceDisconnect(); // disconnect() без ожидания (с отключением SO_LINGER)
void disconnect();
// --------------------------------------------------------------------
int getSocket() const;
......
......@@ -178,7 +178,7 @@ class ModbusClient
/*! функция запрос-ответ */
virtual ModbusRTU::mbErrCode query( ModbusRTU::ModbusAddr addr, ModbusRTU::ModbusMessage& msg,
ModbusRTU::ModbusMessage& reply, timeout_t timeout ) = 0;
ModbusRTU::ModbusMessage& qreply, timeout_t timeout ) = 0;
// -------------------------------------
/*! посылка запроса */
......@@ -191,11 +191,6 @@ class ModbusClient
virtual ModbusRTU::mbErrCode recv_pdu( ModbusRTU::ModbusByte qfunc,
ModbusRTU::ModbusMessage& rbuf, timeout_t timeout );
ModbusRTU::ModbusMessage reply; /*!< буфер для приёма сообщений */
ModbusRTU::ModbusMessage qbuf; /*!< буфер для посылки сообщений */
timeout_t replyTimeOut_ms; /*!< таймаут на ожидание ответа */
timeout_t aftersend_msec; /*!< пауза после посылки запроса */
timeout_t sleepPause_usec; /*!< пауза между попытками чтения символа из канала */
......@@ -209,6 +204,9 @@ class ModbusClient
PassiveTimer tmProcessing;
private:
ModbusRTU::ModbusMessage qreply; /*!< буфер для приёма сообщений */
ModbusRTU::ModbusMessage qbuf; /*!< буфер для посылки сообщений */
};
// -------------------------------------------------------------------------
#endif // ModbusClient_H_
......
......@@ -150,6 +150,7 @@ namespace ModbusRTU
float dat2f( const ModbusData dat1, const ModbusData dat2 );
// -------------------------------------------------------------------------
bool isWriteFunction( SlaveFunctionCode c );
bool isReadFunction( SlaveFunctionCode c );
// -------------------------------------------------------------------------
/*! Заголовок сообщений */
struct ModbusHeader
......
......@@ -24,7 +24,7 @@
//---------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------
static UInterface* ui = 0;
static UInterface* uInterface = 0;
//---------------------------------------------------------------------------
void pyUInterface::uniset_init_params( UTypes::Params* p, const std::string& xmlfile )throw(UException)
{
......@@ -37,7 +37,7 @@ void pyUInterface::uniset_init( int argc, char* argv[], const std::string& xmlfi
try
{
UniSetTypes::uniset_init(argc, argv, xmlfile);
ui = new UInterface();
uInterface = new UInterface();
return;
}
catch( UniSetTypes::Exception& ex )
......@@ -54,7 +54,7 @@ long pyUInterface::getValue( long id )throw(UException)
{
auto conf = UniSetTypes::uniset_conf();
if( !conf || !ui )
if( !conf || !uInterface )
throw USysError();
UniversalIO::IOType t = conf->getIOType(id);
......@@ -67,7 +67,7 @@ long pyUInterface::getValue( long id )throw(UException)
case UniversalIO::DO:
case UniversalIO::AI:
case UniversalIO::AO:
return ui->getValue(id);
return uInterface->getValue(id);
break;
default:
......@@ -96,7 +96,7 @@ void pyUInterface::setValue( long id, long val, long supplier )throw(UException)
{
auto conf = UniSetTypes::uniset_conf();
if( !conf || !ui )
if( !conf || !uInterface )
throw USysError();
UniversalIO::IOType t = conf->getIOType(id);
......@@ -109,7 +109,7 @@ void pyUInterface::setValue( long id, long val, long supplier )throw(UException)
case UniversalIO::DO:
case UniversalIO::AI:
case UniversalIO::AO:
ui->setValue(id, val, supplier);
uInterface->setValue(id, val, supplier);
break;
default:
......
......@@ -60,10 +60,10 @@ throw(ModbusRTU::mbException)
{
ReadCoilMessage msg(addr, start, count);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return ReadCoilRetMessage(reply);
return ReadCoilRetMessage(qreply);
throw mbException(res);
}
......@@ -74,10 +74,10 @@ throw(ModbusRTU::mbException)
{
ReadInputStatusMessage msg(addr, start, count);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return ReadInputStatusRetMessage(reply);
return ReadInputStatusRetMessage(qreply);
throw mbException(res);
}
......@@ -90,10 +90,10 @@ throw(ModbusRTU::mbException)
ReadOutputMessage msg(addr, start, count);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return ReadOutputRetMessage(reply);
return ReadOutputRetMessage(qreply);
throw mbException(res);
}
......@@ -104,10 +104,10 @@ throw(ModbusRTU::mbException)
{
ReadInputMessage msg(addr, start, count);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return ReadInputRetMessage(reply);
return ReadInputRetMessage(qreply);
throw mbException(res);
}
......@@ -119,10 +119,10 @@ throw(ModbusRTU::mbException)
ForceSingleCoilMessage msg(addr, start, cmd);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return ForceSingleCoilRetMessage(reply);
return ForceSingleCoilRetMessage(qreply);
throw mbException(res);
}
......@@ -135,10 +135,10 @@ throw(ModbusRTU::mbException)
WriteSingleOutputMessage msg(addr, start, data);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return WriteSingleOutputRetMessage(reply);
return WriteSingleOutputRetMessage(qreply);
throw mbException(res);
}
......@@ -147,10 +147,10 @@ ForceCoilsRetMessage ModbusClient::write0F( ForceCoilsMessage& msg )
throw(ModbusRTU::mbException)
{
qbuf = msg.transport_msg();
mbErrCode res = query(msg.addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return ForceCoilsRetMessage(reply);
return ForceCoilsRetMessage(qreply);
throw mbException(res);
}
......@@ -160,10 +160,10 @@ WriteOutputRetMessage ModbusClient::write10( WriteOutputMessage& msg )
throw(ModbusRTU::mbException)
{
qbuf = msg.transport_msg();
mbErrCode res = query(msg.addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return WriteOutputRetMessage(reply);
return WriteOutputRetMessage(qreply);
throw mbException(res);
}
......@@ -175,10 +175,10 @@ throw(ModbusRTU::mbException)
{
DiagnosticMessage msg(addr, subfunc, dat);
qbuf = msg.transport_msg();
mbErrCode res = query(msg.addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return DiagnosticRetMessage(reply);
return DiagnosticRetMessage(qreply);
throw mbException(res);
}
......@@ -190,10 +190,10 @@ throw(ModbusRTU::mbException)
{
MEIMessageRDI msg(addr, devID, objID);
qbuf = msg.transport_msg();
mbErrCode res = query(msg.addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(msg.addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return MEIMessageRetRDI(reply);
return MEIMessageRetRDI(qreply);
throw mbException(res);
}
......@@ -213,10 +213,10 @@ throw(ModbusRTU::mbException)
msg.century = century;
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, replyTimeOut_ms);
mbErrCode res = query(addr, qbuf, qreply, replyTimeOut_ms);
if( res == erNoError )
return SetDateTimeRetMessage(reply);
return SetDateTimeRetMessage(qreply);
throw mbException(res);
}
......@@ -320,10 +320,10 @@ throw(ModbusRTU::mbException)
FileTransferMessage msg(addr, idFile, numpack);
qbuf = msg.transport_msg();
mbErrCode res = query(addr, qbuf, reply, part_timeout_msec);
mbErrCode res = query(addr, qbuf, qreply, part_timeout_msec);
if( res == erNoError )
return FileTransferRetMessage(reply);
return FileTransferRetMessage(qreply);
throw mbException(res);
}
......
......@@ -39,9 +39,6 @@ size_t ModbusTCPCore::readNextData(UTCPStream* tcp,
char* buf = new char[max];
if( buf == 0 )
return 0;
try
{
ssize_t l = tcp->receiveBytes(buf, max);
......@@ -114,10 +111,18 @@ size_t ModbusTCPCore::getNextData(UTCPStream* tcp,
if( len <= 0 )
len = 7;
size_t ret = ModbusTCPCore::readNextData(tcp, qrecv, len);
try
{
size_t ret = ModbusTCPCore::readNextData(tcp, qrecv, len);
if( ret == 0 )
return 0;
if( ret == 0 )
return 0;
}
catch( UniSetTypes::CommFailed& ex )
{
if( qrecv.empty() )
return 0;
}
}
size_t i = 0;
......@@ -141,9 +146,6 @@ size_t ModbusTCPCore::readDataFD( int fd, std::queue<unsigned char>& qrecv, size
char* buf = new char[max];
if( buf == 0 )
return 0;
ssize_t l = 0;
size_t cnt = 0;
......@@ -209,10 +211,18 @@ size_t ModbusTCPCore::getDataFD( int fd, std::queue<unsigned char>& qrecv,
if( len == 0 )
len = 7;
size_t ret = ModbusTCPCore::readDataFD(fd, qrecv, len, attempts);
try
{
size_t ret = ModbusTCPCore::readDataFD(fd, qrecv, len, attempts);
if( ret == 0 && qrecv.empty() )
return 0;
if( ret == 0 && qrecv.empty() )
return 0;
}
catch( UniSetTypes::CommFailed& ex )
{
if( qrecv.empty() )
return 0;
}
}
size_t i = 0;
......
......@@ -59,7 +59,7 @@ void ModbusTCPMaster::setChannelTimeout( timeout_t msec )
Poco::Timespan tm = UniSetTimer::millisecToPoco(msec);
Poco::Timespan old = tcp->getReceiveTimeout();;
if( old.microseconds() == tm.microseconds() )
if( old.totalMicroseconds() == tm.totalMicroseconds() )
return;
tcp->setReceiveTimeout(tm);
......@@ -201,7 +201,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
}
cleanInputStream();
tcp->forceDisconnect();
if( tcp )
tcp->forceDisconnect();
return erTimeOut; // return erHardwareError;
}
......@@ -247,12 +248,13 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
if( force_disconnect )
{
if( dlog->is_info() )
dlog->info() << "(query): force disconnect.." << endl;
dlog->info() << "(query): disconnect.." << endl;
// при штатном обмене..лучше дождаться конца "посылки"..
// поэтому применяем disconnect(), а не forceDisconnect()
// (с учётом выставленной опции setLinger(true))
tcp->close();
if( tcp )
tcp->disconnect();
}
return res;
......@@ -267,7 +269,8 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
dlog->info() << "(query): force disconnect.." << endl;
// cleanInputStream();
tcp->forceDisconnect();
if( tcp )
tcp->forceDisconnect();
}
return erTimeOut;
......@@ -303,7 +306,7 @@ mbErrCode ModbusTCPMaster::query( ModbusAddr addr, ModbusMessage& msg,
catch( const std::exception& e )
{
if( dlog->is_warn() )
dlog->crit() << "(query): " << e.what() << std::endl;
dlog->warn() << "(query): " << e.what() << std::endl;
}
return erTimeOut; // erHardwareError
......@@ -385,7 +388,7 @@ bool ModbusTCPMaster::connect( const std::string& addr, int _port, bool closeOld
{
ostringstream s;
s << "(ModbusTCPMaster): connect " << iaddr << ":" << port << " error: " << e.what();
dlog->crit() << iaddr << std::endl;
dlog->crit() << s.str() << std::endl;
}
}
......@@ -426,13 +429,22 @@ bool ModbusTCPMaster::connect( const Poco::Net::SocketAddress& addr, int _port,
tcp->setNoDelay(true);
return true;
}
catch( Poco::TimeoutException& ex)
{
if( dlog->debugging(Debug::CRIT) )
{
ostringstream s;
s << "(ModbusTCPMaster): create connection " << iaddr << ":" << port << " timeout exception";
dlog->crit() << s.str() << std::endl;
}
}
catch( Poco::Net::NetException& ex)
{
if( dlog->debugging(Debug::CRIT) )
{
ostringstream s;
s << "(ModbusTCPMaster): create connection " << iaddr << ":" << port << " error: " << ex.displayText();
dlog->crit() << iaddr << std::endl;
dlog->crit() << s.str() << std::endl;
}
}
catch( const std::exception& e )
......@@ -441,7 +453,7 @@ bool ModbusTCPMaster::connect( const Poco::Net::SocketAddress& addr, int _port,
{
ostringstream s;
s << "(ModbusTCPMaster): connection " << iaddr << ":" << port << " error: " << e.what();
dlog->crit() << iaddr << std::endl;
dlog->crit() << s.str() << std::endl;
}
}
catch( ... )
......@@ -466,7 +478,7 @@ void ModbusTCPMaster::disconnect()
if( !tcp )
return;
tcp->close();
tcp->disconnect(); // close();
tcp = nullptr;
}
// -------------------------------------------------------------------------
......
......@@ -194,6 +194,18 @@ bool ModbusRTU::isWriteFunction( SlaveFunctionCode c )
return false;
}
// -------------------------------------------------------------------------
bool ModbusRTU::isReadFunction( SlaveFunctionCode c )
{
if( c == fnReadCoilStatus ||
c == fnReadInputStatus ||
c == fnReadOutputRegisters ||
c == fnReadInputRegisters )
return true;
return false;
}
// -------------------------------------------------------------------------
std::ostream& ModbusRTU::mbPrintMessage( std::ostream& os, ModbusByte* m, size_t len )
{
// Чтобы не менять настройки 'os'
......
......@@ -14,10 +14,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// -----------------------------------------------------------------------------
#include <functional>
#include <sstream>
#include <cstdlib>
#include "UniSetTypes.h"
#include "PassiveTimer.h"
#include "ThreadCreator.h"
#include "TCPCheck.h"
#include "UTCPStream.h"
// -----------------------------------------------------------------------------
......@@ -76,11 +78,38 @@ void TCPCheck::check_thread()
t.create(ip, port, tout_msec);
t.setKeepAliveParams( (tout_msec > 1000 ? tout_msec / 1000 : 1) );
setResult(true);
t.close();
t.disconnect();
}
catch( ... ) {}
}
// -----------------------------------------------------------------------------
template<typename T>
class TGuard
{
public:
TGuard( T* m, typename ThreadCreator<T>::Action a ):
t(m,a)
{
t.start();
}
~TGuard()
{
if( t.isRunning() )
t.stop();
}
inline bool isRunning()
{
return t.isRunning();
}
protected:
ThreadCreator<T> t;
};
// -----------------------------------------------------------------------------
bool TCPCheck::ping( const std::string& _ip, timeout_t tout, timeout_t sleep_msec, const std::string& _ping_args )
{
ip = _ip;
......@@ -89,17 +118,13 @@ bool TCPCheck::ping( const std::string& _ip, timeout_t tout, timeout_t sleep_mse
setResult(false);
ThreadCreator<TCPCheck> t(this, &TCPCheck::ping_thread);
t.start();
TGuard<TCPCheck> t(this, &TCPCheck::ping_thread);
PassiveTimer pt(tout);
while( !pt.checkTime() && t.isRunning() )
msleep(sleep_msec);
if( t.isRunning() ) // !getResult() )
t.stop();
return result;
}
// -----------------------------------------------------------------------------
......
......@@ -5,7 +5,11 @@ using namespace std;
// -------------------------------------------------------------------------
USocket::~USocket()
{
close();
try
{
close();
}
catch(...){}
}
// -------------------------------------------------------------------------
USocket::USocket( int sock )
......
......@@ -12,7 +12,11 @@ using namespace std;
// -------------------------------------------------------------------------
UTCPSocket::~UTCPSocket()
{
Poco::Net::ServerSocket::close();
try
{
Poco::Net::ServerSocket::close();
}
catch(...){}
}
// -------------------------------------------------------------------------
UTCPSocket::UTCPSocket()
......
......@@ -57,20 +57,40 @@ bool UTCPStream::isSetLinger() const
// -------------------------------------------------------------------------
void UTCPStream::forceDisconnect()
{
if( !isConnected() )
return;
try
{
bool on;
int sec;
Poco::Net::StreamSocket::getLinger(on, sec);
setLinger(false, 0);
}
// catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
try
{
close();
//shutdown();
Poco::Net::StreamSocket::setLinger(on, sec);
}
catch( Poco::Net::NetException& )
// catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
}
// -------------------------------------------------------------------------
void UTCPStream::disconnect()
{
try
{
shutdown();
}
// catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
try
{
close();
}
// catch( Poco::Net::NetException& ex ){}
catch( std::exception& ex ){}
}
// -------------------------------------------------------------------------
int UTCPStream::getSocket() const
......@@ -81,13 +101,13 @@ int UTCPStream::getSocket() const
timeout_t UTCPStream::getTimeout() const
{
auto tm = Poco::Net::StreamSocket::getReceiveTimeout();
return tm.microseconds();
return tm.totalMicroseconds();
}
// -------------------------------------------------------------------------
void UTCPStream::create(const std::string& hname, int port, timeout_t tout_msec )
void UTCPStream::create( const std::string& hname, int port, timeout_t tout_msec )
{
Poco::Net::SocketAddress sa(hname, port);
connect(sa, tout_msec * 1000);
Poco::Net::SocketAddress saddr(hname, port);
connect(saddr, UniSetTimer::millisecToPoco(tout_msec));
setKeepAlive(true);
Poco::Net::StreamSocket::setLinger(true, 1);
setKeepAliveParams();
......@@ -95,7 +115,7 @@ void UTCPStream::create(const std::string& hname, int port, timeout_t tout_msec
// -------------------------------------------------------------------------
bool UTCPStream::isConnected() noexcept
{
return ( Poco::Net::StreamSocket::sockfd() > 0 );
return ( Poco::Net::StreamSocket::sockfd() != POCO_INVALID_SOCKET );
/*
try
{
......
......@@ -920,8 +920,8 @@ throw(ResolveNameError, UniSetTypes::TimeOut )
catch(const CosNaming::NamingContext::NotFound& nf) {}
catch(const CosNaming::NamingContext::InvalidName& nf) {}
catch(const CosNaming::NamingContext::CannotProceed& cp) {}
catch( const Exception ) {}
catch( const CORBA::OBJECT_NOT_EXIST )
catch( const UniSetTypes::Exception& ex ) {}
catch( const CORBA::OBJECT_NOT_EXIST& ex )
{
throw UniSetTypes::ResolveNameError("ObjectNOTExist");
}
......
......@@ -59,8 +59,8 @@ static const int numErrorTags = sizeof(errorTags) / sizeof(error_item);
Debug::type const Debug::ANY = Debug::type(
Debug::INFO | Debug::INIT | Debug::WARN | Debug::CRIT |
Debug::LEVEL1 | Debug::LEVEL2 | Debug::LEVEL3 | Debug::LEVEL4 |
Debug::LEVEL5 | Debug::LEVEL5 | Debug::LEVEL6 | Debug::LEVEL7 |
Debug::LEVEL8 | Debug::LEVEL9 | Debug::REPOSITORY | Debug::SYSTEM |
Debug::LEVEL5 | Debug::LEVEL6 | Debug::LEVEL7 | Debug::LEVEL8 |
Debug::LEVEL9 | Debug::REPOSITORY | Debug::SYSTEM |
Debug::EXCEPTION );
......@@ -124,7 +124,11 @@ void Debug::showTags(ostream& os) noexcept
<< setw(10) << errorTags[i].name
<< " " << errorTags[i].desc << '\n';
os.flush();
try
{
os.flush();
}
catch(...){}
}
std::ostream& operator<<(std::ostream& os, Debug::type level ) noexcept
......@@ -166,7 +170,13 @@ std::string Debug::str( Debug::type level ) noexcept
}
}
return s.str();
try
{
return s.str();
}
catch(...){}
return "";
}
......
......@@ -132,8 +132,7 @@ void LogReader::disconnect()
try
{
//tcp->shutdown();
tcp->close();
tcp->disconnect();
}
catch( const Poco::Net::NetException& e )
{
......@@ -181,7 +180,7 @@ void LogReader::sendCommand(const std::string& _addr, int _port, std::vector<Com
msg.data = c.data;
msg.setLogName(c.logfilter);
unsigned int n = 2; // две попытки на посылку
size_t n = 2; // две попытки на посылку
while( n > 0 )
{
......@@ -245,7 +244,7 @@ void LogReader::sendCommand(const std::string& _addr, int _port, std::vector<Com
// теперь ждём ответ..
try
{
int a = 2;
size_t a = 2;
while( a > 0 && tcp->poll(UniSetTimer::millisecToPoco(reply_timeout), Poco::Net::Socket::SELECT_READ) )
{
......
......@@ -39,28 +39,41 @@ LogServer::~LogServer() noexcept
catch(...){}
}
// -------------------------------------------------------------------------
LogServer::LogServer( std::shared_ptr<LogAgregator> log ) noexcept:
LogServer(static_pointer_cast<DebugStream>(log))
LogServer::LogServer( std::shared_ptr<LogAgregator> log ):
LogServer()
{
elog = dynamic_pointer_cast<DebugStream>(log);
if( !elog )
{
ostringstream err;
err << myname << "(LogServer): dynamic_pointer_cast FAILED! ";
if( mylog.is_info() )
mylog.info() << myname << "(evfinish): terminate..." << endl;
if( mylog.is_crit() )
mylog.crit() << err.str() << endl;
cerr << err.str() << endl;
throw SystemError(err.str());
}
}
// -------------------------------------------------------------------------
LogServer::LogServer( std::shared_ptr<DebugStream> log ) noexcept:
timeout(UniSetTimer::WaitUpTime),
cmdTimeout(2000),
sessLogLevel(Debug::NONE),
sock(0),
elog(log)
LogServer::LogServer( std::shared_ptr<DebugStream> log ):
LogServer()
{
elog = log;
}
// -------------------------------------------------------------------------
LogServer::LogServer() noexcept:
LogServer::LogServer():
timeout(UniSetTimer::WaitUpTime),
cmdTimeout(2000),
sessLogLevel(Debug::NONE),
sock(0),
elog(nullptr)
{
slist.reserve(sessMaxCount);
}
// -------------------------------------------------------------------------
void LogServer::evfinish( const ev::loop_ref& loop )
......@@ -115,6 +128,45 @@ void LogServer::terminate()
loop.evstop(this);
}
// -------------------------------------------------------------------------
bool LogServer::check( bool restart_if_fail )
{
try
{
// для проверки пробуем открыть соединение..
UTCPSocket s(addr, port);
s.close();
return true;
}
catch(...){}
if( !restart_if_fail )
return false;
if( !sock )
return false;
io.stop();
io.set<LogServer, &LogServer::ioAccept>(this);
io.start(sock->getSocket(), ev::READ);
try
{
UTCPSocket s(addr, port);
s.close();
return true;
}
catch( Poco::Net::NetException& ex )
{
ostringstream err;
err << myname << "(check): socket error:" << ex.message();
if( mylog.is_crit() )
mylog.crit() << err.str() << endl;
}
return false;
}
// -------------------------------------------------------------------------
void LogServer::evprepare( const ev::loop_ref& eloop )
{
if( sock )
......@@ -146,8 +198,8 @@ void LogServer::evprepare( const ev::loop_ref& eloop )
sock->setBlocking(false);
io.set<LogServer, &LogServer::ioAccept>(this);
io.set( eloop );
io.set<LogServer, &LogServer::ioAccept>(this);
io.start(sock->getSocket(), ev::READ);
isrunning = true;
}
......@@ -172,9 +224,9 @@ void LogServer::ioAccept( ev::io& watcher, int revents )
}
{
uniset_rwmutex_wrlock l(mutSList);
uniset_rwmutex_rlock l(mutSList);
if( scount >= sessMaxCount )
if( slist.size() >= sessMaxCount )
{
if( mylog.is_crit() )
mylog.crit() << myname << "(LogServer::ioAccept): session limit(" << sessMaxCount << ")" << endl;
......@@ -194,13 +246,10 @@ void LogServer::ioAccept( ev::io& watcher, int revents )
s->signal_logsession_command().connect( sigc::mem_fun(this, &LogServer::onCommand) );
{
uniset_rwmutex_wrlock l(mutSList);
scount++;
slist.push_back(s);
// на первой сессии запоминаем состояние логов
if( scount == 1 )
if( slist.size() == 1 )
saveDefaultLogLevels("ALL");
slist.push_back(s);
}
s->run(watcher.loop);
......@@ -220,14 +269,12 @@ void LogServer::sessionFinished( LogSession* s )
if( i->get() == s )
{
slist.erase(i);
scount--;
break;
}
}
if( slist.empty() )
{
scount = 0;
// восстанавливаем уровни логов по умолчанию
restoreDefaultLogLevels("ALL");
}
......@@ -255,9 +302,14 @@ string LogServer::getShortInfo()
{
ostringstream inf;
inf << "LogServer: " << myname << endl;
inf << "LogServer: " << myname
<< " ["
<< " sessMaxCount=" << sessMaxCount
<< " ]"
<< endl;
{
uniset_rwmutex_wrlock l(mutSList);
uniset_rwmutex_rlock l(mutSList);
for( const auto& s : slist )
inf << " " << s->getShortInfo() << endl;
......
......@@ -74,7 +74,7 @@ LogSession::LogSession( const Poco::Net::StreamSocket& s, std::shared_ptr<DebugS
if( iaddr.host().toString().empty() )
{
ostringstream err;
err << "(ModbusTCPSession): unknonwn ip(0.0.0.0) client disconnected?!";
err << "(LogSession): unknonwn ip(0.0.0.0) client disconnected?!";
if( mylog.is_crit() )
mylog.crit() << err.str() << endl;
......@@ -107,7 +107,7 @@ LogSession::LogSession( const Poco::Net::StreamSocket& s, std::shared_ptr<DebugS
if( log )
conn = log->signal_stream_event().connect( sigc::mem_fun(this, &LogSession::logOnEvent) );
else
mylog.crit() << "LOG NULL!!" << endl;
mylog.crit() << "(LogSession): LOG NULL!!" << endl;
}
// -------------------------------------------------------------------------
void LogSession::logOnEvent( const std::string& s ) noexcept
......@@ -137,11 +137,19 @@ void LogSession::logOnEvent( const std::string& s ) noexcept
if( logbuf.size() >= maxRecordsNum )
{
numLostMsg++;
if( numLostMsg > maxRecordsNum )
{
// видимо клиент отвалился или совсем не успевает читать
// разрываем сессию..
if( mylog.is_info() )
mylog.info() << peername << "(LogSession::onEvent): too many lost messages. Close session.." << endl;
cancelled = true;
}
if( !lostMsg )
{
ostringstream err;
err << "The buffer is full. Message is lost...(size of buffer " << maxRecordsNum << ")" << endl;
err << "(LogSession): The buffer is full. Message is lost...(size of buffer " << maxRecordsNum << ")" << endl;
logbuf.emplace(new UTCPCore::Buffer(std::move(err.str())));
lostMsg = true;
}
......@@ -163,7 +171,7 @@ void LogSession::run( const ev::loop_ref& loop ) noexcept
setSessionLogLevel(Debug::ANY);
if( mylog.is_info() )
mylog.info() << peername << "(run): run session.." << endl;
mylog.info() << peername << "(LogSession::run): run session.." << endl;
asyncEvent.set(loop);
cmdTimer.set(loop);
......@@ -178,7 +186,7 @@ void LogSession::run( const ev::loop_ref& loop ) noexcept
void LogSession::terminate()
{
if( mylog.is_info() )
mylog.info() << peername << "(terminate)..." << endl;
mylog.info() << peername << "(LogSession::terminate)..." << endl;
cancelled = true;
......@@ -196,6 +204,7 @@ void LogSession::terminate()
logbuf.pop();
}
sock->disconnect();
sock->close();
final();
}
......@@ -205,7 +214,7 @@ void LogSession::event( ev::async& watcher, int revents ) noexcept
if( EV_ERROR & revents )
{
if( mylog.is_crit() )
mylog.crit() << peername << "(event): EVENT ERROR.." << endl;
mylog.crit() << peername << "(LogSession::event): EVENT ERROR.." << endl;
return;
}
......@@ -218,7 +227,7 @@ void LogSession::callback( ev::io& watcher, int revents ) noexcept
if( EV_ERROR & revents )
{
if( mylog.is_crit() )
mylog.crit() << peername << "(callback): EVENT ERROR.." << endl;
mylog.crit() << peername << "(LogSession::callback): EVENT ERROR.." << endl;
return;
}
......@@ -241,10 +250,10 @@ void LogSession::callback( ev::io& watcher, int revents ) noexcept
catch(...){}
}
if( cancelled )
if( cancelled.load() )
{
if( mylog.is_info() )
mylog.info() << peername << ": stop session... disconnect.." << endl;
mylog.info() << peername << "LogSession: stop session... disconnect.." << endl;
io.stop();
cmdTimer.stop();
......@@ -262,7 +271,7 @@ void LogSession::callback( ev::io& watcher, int revents ) noexcept
// -------------------------------------------------------------------------
void LogSession::writeEvent( ev::io& watcher )
{
if( cancelled )
if( cancelled.load() )
return;
UTCPCore::Buffer* buffer = 0;
......@@ -283,17 +292,17 @@ void LogSession::writeEvent( ev::io& watcher )
if( !buffer )
return;
ssize_t ret = write(watcher.fd, buffer->dpos(), buffer->nbytes());
ssize_t ret = ::write(watcher.fd, buffer->dpos(), buffer->nbytes());
if( ret < 0 )
{
if( mylog.is_warn() )
mylog.warn() << peername << "(writeEvent): write to socket error(" << errno << "): " << strerror(errno) << endl;
mylog.warn() << peername << "(LogSession::writeEvent): write to socket error(" << errno << "): " << strerror(errno) << endl;
if( errno == EPIPE )
if( errno == EPIPE || errno == EBADF )
{
if( mylog.is_warn() )
mylog.warn() << peername << "(writeEvent): write error.. terminate session.." << endl;
mylog.warn() << peername << "(LogSession::writeEvent): write error.. terminate session.." << endl;
cancelled = true;
}
......@@ -344,7 +353,7 @@ size_t LogSession::readData( unsigned char* buf, int len )
if( res < 0 )
{
if( errno != EAGAIN && mylog.is_warn() )
mylog.warn() << peername << "(readData): read from socket error(" << errno << "): " << strerror(errno) << endl;
mylog.warn() << peername << "(LogSession::readData): read from socket error(" << errno << "): " << strerror(errno) << endl;
return 0;
}
......@@ -362,7 +371,7 @@ size_t LogSession::readData( unsigned char* buf, int len )
}
mylog.info() << peername << "(readData): client disconnected.." << endl;
mylog.info() << peername << "(LogSession::readData): client disconnected.." << endl;
cancelled = true;
return 0;
}
......@@ -382,13 +391,13 @@ void LogSession::readEvent( ev::io& watcher ) noexcept
if( ret != sizeof(msg) || msg.magic != LogServerTypes::MAGICNUM )
{
if( mylog.is_warn() )
mylog.warn() << peername << "(readEvent): BAD MESSAGE..." << endl;
mylog.warn() << peername << "(LogSession::readEvent): BAD MESSAGE..." << endl;
return;
}
if( mylog.is_info() )
mylog.info() << peername << "(readEvent): receive command: '" << msg.cmd << "'" << endl;
mylog.info() << peername << "(LogSession::readEvent): receive command: '" << msg.cmd << "'" << endl;
string cmdLogName(msg.logname);
......@@ -399,7 +408,7 @@ void LogSession::readEvent( ev::io& watcher ) noexcept
catch( std::exception& ex )
{
if( mylog.is_warn() )
mylog.warn() << peername << "(readEvent): " << ex.what() << endl;
mylog.warn() << peername << "(LogSession::readEvent): " << ex.what() << endl;
}
catch(...){}
......@@ -550,7 +559,7 @@ void LogSession::cmdProcessing( const string& cmdLogName, const LogServerTypes::
catch( std::exception& ex )
{
if( mylog.is_warn() )
mylog.warn() << peername << "(cmdProcessing): " << ex.what() << endl;
mylog.warn() << peername << "(LogSession::cmdProcessing): " << ex.what() << endl;
}
}
// -------------------------------------------------------------------------
......@@ -559,7 +568,7 @@ void LogSession::onCmdTimeout( ev::timer& watcher, int revents ) noexcept
if( EV_ERROR & revents )
{
if( mylog.is_crit() )
mylog.crit() << peername << "(onCmdTimeout): EVENT ERROR.." << endl;
mylog.crit() << peername << "(LogSession::onCmdTimeout): EVENT ERROR.." << endl;
return;
}
......@@ -573,7 +582,7 @@ void LogSession::onCheckConnectionTimer( ev::timer& watcher, int revents ) noexc
if( EV_ERROR & revents )
{
if( mylog.is_crit() )
mylog.crit() << peername << "(onCheckConnectionTimer): EVENT ERROR.." << endl;
mylog.crit() << peername << "(LogSession::onCheckConnectionTimer): EVENT ERROR.." << endl;
return;
}
......@@ -588,10 +597,12 @@ void LogSession::onCheckConnectionTimer( ev::timer& watcher, int revents ) noexc
// если клиент уже отвалился.. то при попытке write.. сессия будет закрыта.
// длинное сообщение ("keep alive message") забивает логи, что потом неудобно смотреть, поэтому пишем "пустоту"
// длинное сообщение ("keep alive message") забивает логи, что потом неудобно смотреть
// поэтому используем "пробел и возврат на один символ"
try
{
logbuf.emplace(new UTCPCore::Buffer(""));
//
logbuf.emplace(new UTCPCore::Buffer(" \b"));
}
catch(...){}
......@@ -649,7 +660,7 @@ string LogSession::getShortInfo() noexcept
ostringstream inf;
inf << "client: " << caddr << endl
inf << "client: " << caddr << " :"
<< " buffer[" << maxRecordsNum << "]: size=" << sz
<< " maxCount=" << maxCount
<< " minSizeMsg=" << minSizeMsg
......@@ -660,3 +671,8 @@ string LogSession::getShortInfo() noexcept
return std::move(inf.str());
}
// ---------------------------------------------------------------------
string LogSession::name() const noexcept
{
return caddr;
}
// ---------------------------------------------------------------------
......@@ -24,9 +24,10 @@
using namespace UniSetTypes;
using namespace std;
// -----------------------------------------------------------------------------------------
ObjectIndex_XML::ObjectIndex_XML(const string& xmlfile, size_t minSize ):
omap(minSize)
ObjectIndex_XML::ObjectIndex_XML(const string& xmlfile, size_t minSize )
{
omap.reserve(minSize);
shared_ptr<UniXML> xml = make_shared<UniXML>();
// try
// {
......@@ -36,9 +37,9 @@ ObjectIndex_XML::ObjectIndex_XML(const string& xmlfile, size_t minSize ):
// catch(...){}
}
// -----------------------------------------------------------------------------------------
ObjectIndex_XML::ObjectIndex_XML(const std::shared_ptr<UniXML>& xml, size_t minSize ):
omap(minSize)
ObjectIndex_XML::ObjectIndex_XML(const std::shared_ptr<UniXML>& xml, size_t minSize )
{
omap.reserve(minSize);
build(xml);
}
// -----------------------------------------------------------------------------------------
......@@ -111,6 +112,7 @@ void ObjectIndex_XML::build( const std::shared_ptr<UniXML>& xml )
//
omap.resize(ind);
omap.shrink_to_fit();
// omap[ind].repName=NULL;
// omap[ind].textName=NULL;
// omap[ind].id = ind;
......@@ -199,7 +201,7 @@ size_t ObjectIndex_XML::read_section( const std::shared_ptr<UniXML>& xml, const
// cout << "read: " << "(" << ind << ") " << omap[ind].repName << "\t" << omap[ind].textName << endl;
ind++;
if( (unsigned)ind >= omap.size() )
if( ind >= omap.size() )
{
uinfo << "(ObjectIndex_XML::build): не хватило размера массива maxSize=" << omap.size()
<< "... Делаем resize + 100" << endl;
......
......@@ -343,6 +343,8 @@ void UniSetManager::objects(OManagerCommand cmd)
{
ucrit << myname << "(objects): " << ex << endl;
ucrit << myname << "(objects): не смог зарегистрировать (разрегистрировать) объект -->" << li->getName() << endl;
if( cmd == activ )
std::terminate();
}
catch( const CORBA::SystemException& ex )
{
......@@ -360,6 +362,9 @@ void UniSetManager::objects(OManagerCommand cmd)
ucrit << myname << "(objects): file: " << fe.file()
<< " line: " << fe.line()
<< " mesg: " << fe.errmsg() << endl;
if( cmd == activ )
std::terminate();
}
}
} // unlock
......
......@@ -32,8 +32,6 @@ using namespace UniSetTypes;
NCRestorer_XML::NCRestorer_XML( const string& fname ):
s_filterField(""),
s_filterValue(""),
c_filterField(""),
c_filterValue(""),
t_filterField(""),
t_filterValue(""),
fname(fname),
......@@ -47,8 +45,6 @@ NCRestorer_XML::NCRestorer_XML(const string& fname,
const std::string& f_value):
s_filterField(f_field),
s_filterValue(f_value),
c_filterField(""),
c_filterValue(""),
t_filterField(""),
t_filterValue(""),
fname(fname),
......
......@@ -3,6 +3,7 @@
#include <memory>
#include <sstream>
#include <thread>
#include <future>
#include "Mutex.h"
#include "UniSetTypes.h"
......@@ -47,28 +48,47 @@ void la_logOnEvent( const std::string& s )
la_msg << s;
}
// --------------------------------------------------------------------------
void readlog_thread1()
bool readlog_thread1()
{
LogReader lr;
lr.setinTimeout(readTimeout);
lr.signal_stream_event().connect( sigc::ptr_fun(rlog1OnEvent) );
lr.setReadCount(1);
lr.setLogLevel(Debug::ANY);
while( !g_read_cancel )
lr.readlogs(ip, port); // ,LogServerTypes::cmdNOP,0,"",true);
try
{
LogReader lr;
lr.setinTimeout(readTimeout);
lr.signal_stream_event().connect( sigc::ptr_fun(rlog1OnEvent) );
lr.setReadCount(1);
lr.setLogLevel(Debug::ANY);
while( !g_read_cancel )
lr.readlogs(ip, port); // ,LogServerTypes::cmdNOP,0,"",true);
return true;
}
catch( std::exception& ex )
{
}
return false;
}
// --------------------------------------------------------------------------
void readlog_thread2()
bool readlog_thread2()
{
LogReader lr;
lr.setinTimeout(readTimeout);
lr.signal_stream_event().connect( sigc::ptr_fun(rlog2OnEvent) );
lr.setReadCount(1);
lr.setLogLevel(Debug::ANY);
while( !g_read_cancel )
lr.readlogs(ip, port); // ,LogServerTypes::cmdNOP,0,"",true);
try
{
LogReader lr;
lr.setinTimeout(readTimeout);
lr.signal_stream_event().connect( sigc::ptr_fun(rlog2OnEvent) );
lr.setReadCount(1);
lr.setLogLevel(Debug::ANY);
while( !g_read_cancel )
lr.readlogs(ip, port); // ,LogServerTypes::cmdNOP,0,"",true);
return true;
}
catch( std::exception& ex )
{
}
return false;
}
// --------------------------------------------------------------------------
TEST_CASE("LogAgregator", "[LogServer][LogAgregator]" )
......@@ -133,7 +153,7 @@ TEST_CASE("LogServer", "[LogServer]" )
REQUIRE( ls.isRunning() );
msg.str("");
auto r_thr = make_shared<std::thread>(readlog_thread1);
auto ret = std::async(std::launch::async, readlog_thread1); // make_shared<std::thread>(readlog_thread1);
msleep(100); // небольшая пауза на создание потока и т.п.
......@@ -168,10 +188,7 @@ TEST_CASE("LogServer", "[LogServer]" )
}
g_read_cancel = true;
msleep(readTimeout);
if( r_thr->joinable() )
r_thr->join();
ret.get();
}
// --------------------------------------------------------------------------
TEST_CASE("MaxSessions", "[LogServer]" )
......@@ -205,11 +222,11 @@ TEST_CASE("MaxSessions", "[LogServer]" )
msg.str("");
msg2.str("");
auto r1_thr = make_shared<std::thread>(readlog_thread1);
auto ret1 = std::async(std::launch::async, readlog_thread1); // make_shared<std::thread>(readlog_thread1);
msleep(500); // пауза чтобы первый заведомо успел подключиться раньше второго..
auto r2_thr = make_shared<std::thread>(readlog_thread2);
auto ret2 = std::async(std::launch::async, readlog_thread1); // make_shared<std::thread>(readlog_thread2);
msleep(100); // небольшая пауза на создание потока и т.п.
......@@ -240,13 +257,8 @@ TEST_CASE("MaxSessions", "[LogServer]" )
}
g_read_cancel = true;
msleep(readTimeout);
if( r1_thr->joinable() )
r1_thr->join();
if( r2_thr->joinable() )
r2_thr->join();
ret1.get();
ret2.get();
}
// --------------------------------------------------------------------------
TEST_CASE("LogAgregator regexp", "[LogAgregator]" )
......
......@@ -16,17 +16,23 @@ static atomic_bool cancel = {false};
// --------------------------------------------------------
bool run_test_server()
{
UTCPSocket sock(host, port);
while( !cancel )
try
{
if( sock.poll(PassiveTimer::millisecToPoco(500), Poco::Net::Socket::SELECT_READ) )
UTCPSocket sock(host, port);
while( !cancel )
{
if( sock.poll(PassiveTimer::millisecToPoco(500), Poco::Net::Socket::SELECT_READ) )
{
}
}
return true;
}
catch(...){}
return true;
return false;
}
// --------------------------------------------------------
// вспомогательный класс для гарантированного завершения потока..
......
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