Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
4ecc9a59
Commit
4ecc9a59
authored
Jul 26, 2017
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(MBSlave): добавил таймер контроля работы основного потока обмена (eventloop),
и перезапуск в случае его "вылета".
parent
17792ffe
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
16 deletions
+117
-16
MBSlave.cc
extensions/ModbusSlave/MBSlave.cc
+56
-6
MBSlave.h
extensions/ModbusSlave/MBSlave.h
+10
-0
EventLoopServer.h
include/EventLoopServer.h
+4
-2
EventLoopServer.cc
src/Processes/EventLoopServer.cc
+47
-8
No files found.
extensions/ModbusSlave/MBSlave.cc
View file @
4ecc9a59
...
...
@@ -150,6 +150,10 @@ namespace uniset
timeout_t
aftersend_pause
=
conf
->
getArgInt
(
"--"
+
prefix
+
"-aftersend-pause"
,
it
.
getProp
(
"afterSendPause"
));
checkExchangeTime
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-check-exchange-time"
,
it
.
getProp
(
"checkExchangeTime"
),
10000
);
vmonit
(
checkExchangeTime
);
vmonit
(
restartTCPServerCount
);
mbtype
=
conf
->
getArgParam
(
"--"
+
prefix
+
"-type"
,
it
.
getProp
(
"type"
));
if
(
mbtype
==
"RTU"
)
...
...
@@ -646,7 +650,12 @@ namespace uniset
// для обновления пороговых датчиков
tcpserver
->
signal_post_receive
().
connect
(
sigc
::
mem_fun
(
this
,
&
MBSlave
::
postReceiveEvent
)
);
mbinfo
<<
myname
<<
"(execute_tcp): run tcpserver ("
runTCPServer
();
}
// -------------------------------------------------------------------------
void
MBSlave
::
runTCPServer
()
{
mbinfo
<<
myname
<<
"(runTCPServer): run tcpserver ("
<<
tcpserver
->
getInetAddress
()
<<
":"
<<
tcpserver
->
getInetPort
()
<<
")"
<<
"["
...
...
@@ -713,12 +722,9 @@ namespace uniset
throw
;
}
cerr
<<
myname
<<
"**************** "
<<
endl
;
msleep
(
tcpRepeatCreateSocketPause
);
}
// tcpCancelled = true;
// mbinfo << myname << "(execute_tcp): tcpserver stopped.." << endl;
}
// -------------------------------------------------------------------------
void
MBSlave
::
updateStatistics
()
...
...
@@ -787,10 +793,29 @@ namespace uniset
// -------------------------------------------------------------------------
void
MBSlave
::
updateTCPStatistics
()
{
#if 0
// тестирование вылета при SEGFAULT
// или перезапуска при невыловленном EXCEPTION
// для mainloop
static size_t upCounter = 0;
upCounter++;
if( ++upCounter > 5 )
{
// IOMap::iterator i;
// cout << "SEGFAULT: " << i->first << endl;
upCounter = 0;
cerr << ".....THROW...." << endl;
throw std::string("TEST STRING EXCEPTION");
}
#endif
// ВНИМАНИЕ! Эта функция вызывается из основного eventLoop
// поэтому она должна быть максимально быстрой и безопасной
// иначе накроется весь обмен
// т.к. на это время останавливается работа основного потока (eventLoop)
// принимающего запросы
try
{
...
...
@@ -951,6 +976,8 @@ namespace uniset
thr
->
start
();
else
if
(
mbtype
==
"TCP"
)
execute_tcp
();
askTimer
(
tmCheckExchange
,
checkExchangeTime
);
}
break
;
...
...
@@ -1083,9 +1110,25 @@ namespace uniset
}
}
// ------------------------------------------------------------------------------------------
void
MBSlave
::
timerInfo
(
const
TimerMessage
*
tm
)
{
if
(
tm
->
id
==
tmCheckExchange
)
{
if
(
!
tcpserver
)
return
;
if
(
!
tcpserver
->
isActive
()
)
{
mbwarn
<<
myname
<<
"(timerInfo): tcpserver thread failed! restart.."
<<
endl
;
restartTCPServerCount
++
;
runTCPServer
();
}
}
}
// ------------------------------------------------------------------------------------------
bool
MBSlave
::
activateObject
()
{
// блокирование обработки Star
s
p
// блокирование обработки Star
tU
p
// пока не пройдёт инициализация датчиков
// см. sysCommand()
{
...
...
@@ -2839,7 +2882,14 @@ namespace uniset
inf
<<
" "
<<
ModbusRTU
::
addr2str
(
m
.
first
)
<<
": iomap="
<<
m
.
second
.
size
()
<<
endl
;
inf
<<
" myaddr: "
<<
ModbusServer
::
vaddr2str
(
vaddr
)
<<
endl
;
inf
<<
"Statistic: connectionCount="
<<
connCount
<<
" smPingOK="
<<
smPingOK
<<
endl
;
inf
<<
"Statistic:"
<<
" connectionCount="
<<
connCount
<<
" smPingOK="
<<
smPingOK
;
if
(
tcpserver
)
inf
<<
" restartTCPServerCount="
<<
restartTCPServerCount
;
inf
<<
endl
;
if
(
sslot
)
// т.е. если у нас tcp
{
...
...
extensions/ModbusSlave/MBSlave.h
View file @
4ecc9a59
...
...
@@ -500,6 +500,7 @@ namespace uniset
virtual
void
sysCommand
(
const
uniset
::
SystemMessage
*
msg
)
override
;
virtual
void
sensorInfo
(
const
uniset
::
SensorMessage
*
sm
)
override
;
virtual
void
timerInfo
(
const
uniset
::
TimerMessage
*
tm
)
override
;
void
askSensors
(
UniversalIO
::
UIOCommand
cmd
);
void
waitSMReady
();
virtual
void
execute_rtu
();
...
...
@@ -508,6 +509,7 @@ namespace uniset
virtual
void
updateTCPStatistics
();
virtual
void
updateThresholds
();
virtual
void
postReceiveEvent
(
ModbusRTU
::
mbErrCode
res
);
void
runTCPServer
();
virtual
bool
activateObject
()
override
;
virtual
bool
deactivateObject
()
override
;
...
...
@@ -516,6 +518,13 @@ namespace uniset
virtual
void
sigterm
(
int
signo
)
override
;
virtual
void
finalThread
();
enum
Timer
{
tmCheckExchange
};
uniset
::
timeout_t
checkExchangeTime
=
{
10000
};
// контроль "живости" потока обмена, мсек
virtual
void
initIterators
();
bool
initItem
(
UniXML
::
iterator
&
it
);
bool
readItem
(
const
std
::
shared_ptr
<
UniXML
>&
xml
,
UniXML
::
iterator
&
it
,
xmlNode
*
sec
);
...
...
@@ -566,6 +575,7 @@ namespace uniset
PassiveTimer
ptTimeout
;
long
connCount
=
{
0
};
long
restartTCPServerCount
=
{
0
};
std
::
atomic_bool
activated
=
{
false
};
std
::
atomic_bool
cancelled
=
{
false
};
...
...
include/EventLoopServer.h
View file @
4ecc9a59
...
...
@@ -39,13 +39,14 @@ namespace uniset
*/
bool
async_evrun
(
size_t
waitRunningTimeout_msec
=
60000
);
void
evstop
();
/*!< остановить раннее запущенный поток (async_run) */
/*! синхронный запуск
* функция вернёт управление, только в случае неудачного запуска
* либо если evrun уже был вызван
*/
bool
evrun
();
void
evstop
();
/*!< остановить раннее запущенный поток (event loop) */
ev
::
dynamic_loop
loop
;
private
:
...
...
@@ -57,6 +58,7 @@ namespace uniset
std
::
atomic_bool
cancelled
=
{
false
};
std
::
atomic_bool
isactive
=
{
false
};
std
::
timed_mutex
run_mutex
;
ev
::
async
evterm
;
std
::
shared_ptr
<
std
::
thread
>
thr
;
...
...
src/Processes/EventLoopServer.cc
View file @
4ecc9a59
...
...
@@ -24,17 +24,38 @@ namespace uniset
// ---------------------------------------------------------------------------
bool
EventLoopServer
::
evrun
()
{
{
std
::
lock_guard
<
std
::
timed_mutex
>
l
(
run_mutex
);
if
(
isactive
)
return
false
;
isactive
=
true
;
}
defaultLoop
();
// <-- здесь бесконечный цикл..
return
false
;
}
// ---------------------------------------------------------------------------
bool
EventLoopServer
::
async_evrun
(
size_t
timeout_msec
)
{
if
(
!
run_mutex
.
try_lock_for
(
std
::
chrono
::
milliseconds
(
timeout_msec
))
)
return
false
;
std
::
lock_guard
<
std
::
timed_mutex
>
l
(
run_mutex
,
std
::
adopt_lock
);
if
(
isactive
)
return
true
;
isactive
=
true
;
if
(
thr
)
{
if
(
thr
->
joinable
()
)
thr
->
join
();
thr
=
nullptr
;
}
if
(
!
thr
)
thr
=
make_shared
<
std
::
thread
>
(
[
&
]
{
defaultLoop
();
}
);
...
...
@@ -43,7 +64,9 @@ namespace uniset
// если запуститься не удалось
if
(
!
ret
&&
thr
)
{
thr
->
join
();
if
(
thr
->
joinable
()
)
thr
->
join
();
thr
=
nullptr
;
}
...
...
@@ -57,12 +80,26 @@ namespace uniset
// -------------------------------------------------------------------------
void
EventLoopServer
::
evstop
()
{
cancelled
=
true
;
evterm
.
send
();
{
std
::
lock_guard
<
std
::
timed_mutex
>
l
(
run_mutex
);
if
(
thr
&&
!
isactive
)
{
if
(
thr
->
joinable
()
)
thr
->
join
();
thr
=
nullptr
;
return
;
}
cancelled
=
true
;
evterm
.
send
();
}
if
(
thr
)
{
thr
->
join
();
if
(
thr
->
joinable
()
)
thr
->
join
();
thr
=
nullptr
;
}
}
...
...
@@ -115,10 +152,12 @@ namespace uniset
cerr
<<
"(EventLoopServer::defaultLoop): UNKNOWN EXCEPTION.."
<<
endl
;
}
isrunning
=
false
;
looprunOK_event
.
notify_all
();
isactive
=
false
;
{
std
::
lock_guard
<
std
::
timed_mutex
>
l
(
run_mutex
);
isrunning
=
false
;
looprunOK_event
.
notify_all
();
isactive
=
false
;
}
}
// -------------------------------------------------------------------------
bool
EventLoopServer
::
waitDefaultLoopRunning
(
size_t
waitTimeout_msec
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment