Commit e23632d7 authored by Pavel Vainerman's avatar Pavel Vainerman

Масштабно убрал функцию sigterm, т.к. по сути она дублирует deactivateObject().

А так же сделал прерываемый waitSMReady().
parent ce6224ef
......@@ -193,7 +193,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::preAskSensors( UniversalIO::UIOComm
mycrit &lt;&lt; myname
&lt;&lt; "(preAskSensors): ************* don`t activated?! ************" &lt;&lt; endl;
for( ;; )
while( !cancelled )
{
try
{
......
......@@ -244,7 +244,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::preAskSensors( UniversalIO::UIOComm
mycrit &lt;&lt; myname
&lt;&lt; "(preAskSensors): ************* don`t activated?! ************" &lt;&lt; endl;
for( ;; )
while( !cancelled )
{
try
{
......
......@@ -271,8 +271,8 @@
virtual void askSensors( UniversalIO::UIOCommand cmd ){}
virtual void sensorInfo( const uniset::SensorMessage* sm ) override{}
virtual void timerInfo( const uniset::TimerMessage* tm ) override{}
virtual void sigterm( int signo ) override;
virtual bool activateObject() override;
virtual bool deactivateObject() override;
virtual std::string getMonitInfo() const { return ""; } /*!&lt; пользовательская информация выводимая в getInfo() */
virtual std::string getTypeOfMessage( int t ) const { return uniset::strTypeOfMessage(t); } /*!&lt; получение названия типа сообщения. Используется в getInfo() */
<xsl:if test="normalize-space($DISABLE_REST_API)!='1'">
......@@ -326,7 +326,8 @@
inline const std::string getProp(const std::string&amp; name) { return uniset::uniset_conf()->getProp(confnode, name); }
uniset::timeout_t smReadyTimeout; /*!&lt; время ожидания готовности SM */
std::atomic_bool activated;
std::atomic_bool activated = { false };
std::atomic_bool cancelled = { false };
uniset::timeout_t activateTimeout; /*!&lt; время ожидания готовности UniSetObject к работе */
uniset::PassiveTimer ptStartUpTimeout; /*!&lt; время на блокировку обработки WatchDog, если недавно был StartUp */
int askPause; /*!&lt; пауза между неудачными попытками заказать датчики */
......@@ -798,14 +799,6 @@ uniset::ObjectId <xsl:value-of select="$CLASSNAME"/>_SK::idval( long* p ) const
}
</xsl:if>
// -----------------------------------------------------------------------------
void <xsl:value-of select="$CLASSNAME"/>_SK::sigterm( int signo )
{
<xsl:if test="normalize-space($BASECLASS)!=''"><xsl:value-of select="normalize-space($BASECLASS)"/>::sigterm(signo);</xsl:if>
<xsl:if test="normalize-space($BASECLASS)=''">UniSetObject::sigterm(signo);</xsl:if>
active = false;
}
// -----------------------------------------------------------------------------
bool <xsl:value-of select="$CLASSNAME"/>_SK::activateObject()
{
// блокирование обработки Startup
......@@ -821,6 +814,13 @@ bool <xsl:value-of select="$CLASSNAME"/>_SK::activateObject()
return true;
}
// -----------------------------------------------------------------------------
bool <xsl:value-of select="$CLASSNAME"/>_SK::deactivateObject()
{
cancelled = true;
<xsl:if test="normalize-space($BASECLASS)!=''">return <xsl:value-of select="normalize-space($BASECLASS)"/>::deactivateObject();</xsl:if>
<xsl:if test="normalize-space($BASECLASS)=''">return UniSetObject::deactivateObject();</xsl:if>
}
// -----------------------------------------------------------------------------
void <xsl:value-of select="$CLASSNAME"/>_SK::preTimerInfo( const uniset::TimerMessage* _tm )
{
timerInfo(_tm);
......@@ -844,7 +844,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::waitSM( int wait_msec, ObjectId _te
&lt;&lt; " testID=" &lt;&lt; _testID &lt;&lt; endl;
// waitReady можно использовать т.к. датчик это по сути IONotifyController
if( !ui-&gt;waitReady(_testID,wait_msec) )
if( !ui-&gt;waitReadyWithCancellation(_testID,wait_msec,cancelled) )
{
ostringstream err;
err &lt;&lt; myname
......
......@@ -78,11 +78,6 @@ void TestGen::timerInfo( const TimerMessage* tm )
}
}
// -----------------------------------------------------------------------------
void TestGen::sigterm( int signo )
{
TestGen_SK::sigterm(signo);
}
// -----------------------------------------------------------------------------
#ifndef DISABLE_REST_API
void TestGen::httpGetUserData( Poco::JSON::Object::Ptr& jdata )
{
......
......@@ -18,7 +18,6 @@ class TestGen:
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void sigterm( int signo ) override;
#ifndef DISABLE_REST_API
virtual void httpGetUserData( Poco::JSON::Object::Ptr& jdata ) override;
#endif
......
......@@ -28,8 +28,3 @@ void TestGenAlone::timerInfo( const TimerMessage* tm )
{
}
// -----------------------------------------------------------------------------
void TestGenAlone::sigterm( int signo )
{
TestGenAlone_SK::sigterm(signo);
}
// -----------------------------------------------------------------------------
......@@ -16,7 +16,6 @@ class TestGenAlone:
virtual void step() override;
void sensorInfo( const uniset::SensorMessage* sm ) override;
void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sigterm( int signo ) override;
private:
};
......
......@@ -450,7 +450,7 @@ void DBServer_PostgreSQL::timerInfo( const uniset::TimerMessage* tm )
}
}
//--------------------------------------------------------------------------------------------
void DBServer_PostgreSQL::sigterm( int signo )
bool DBServer_PostgreSQL::deactivateObject()
{
if( db && connect_ok )
{
......@@ -461,7 +461,7 @@ void DBServer_PostgreSQL::sigterm( int signo )
catch(...) {}
}
DBServer::sigterm(signo);
return DBServer::deactivateObject();
}
//--------------------------------------------------------------------------------------------
std::shared_ptr<DBServer_PostgreSQL> DBServer_PostgreSQL::init_dbserver( int argc, const char* const* argv,
......
......@@ -85,7 +85,7 @@ namespace uniset
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void confirmInfo( const uniset::ConfirmMessage* cmsg ) override;
virtual void sigterm( int signo ) override;
virtual bool deactivateObject() override;
bool writeToBase( const std::string& query );
void createTables( std::shared_ptr<PostgreSQLInterface>& db );
......
......@@ -69,7 +69,6 @@ namespace uniset
maxCardNum(10),
activated(false),
readconf_ok(false),
term(false),
testMode_as(uniset::DefaultObjectId),
testmode(tmNone),
prev_testmode(tmNone)
......@@ -406,7 +405,7 @@ namespace uniset
ioinfo << myname << "(iothread): run..." << endl;
while( !term )
while( !cancelled )
{
try
{
......@@ -475,14 +474,13 @@ namespace uniset
iolog3 << myname << "(execute): catch ..." << endl;
}
if( term )
if( cancelled )
break;
msleep( polltime );
}
ioinfo << myname << "(iothread): terminated..." << endl;
term = false;
}
// --------------------------------------------------------------------------------
void IOControl::iopoll()
......@@ -505,7 +503,7 @@ namespace uniset
for( auto it = iomap.begin(); it != iomap.end(); ++it, i++ )
{
if( term )
if( cancelled )
break;
auto io = (*it);
......@@ -537,7 +535,7 @@ namespace uniset
// Опрос приоритетной очереди
for( const auto& it : pmap )
{
if( term )
if( cancelled )
break;
if( it.priority > 2 )
......@@ -909,19 +907,13 @@ namespace uniset
// ------------------------------------------------------------------------------------------
bool IOControl::deactivateObject()
{
sigterm(0);
return UniSetObject::deactivateObject();
}
// ------------------------------------------------------------------------------------------
void IOControl::sigterm( int signo )
{
term = true;
cancelled = true;
if( ioThread && ioThread->isRunning() )
ioThread->join();
if( noCards )
return;
return UniSetObject::deactivateObject();
// выставляем безопасные состояния
for( const auto& it : iomap )
......@@ -954,6 +946,8 @@ namespace uniset
iolog3 << myname << "(sigterm): " << ex.what() << endl;
}
}
return UniSetObject::deactivateObject();
}
// -----------------------------------------------------------------------------
void IOControl::initOutputs()
......@@ -1427,20 +1421,6 @@ namespace uniset
waitSM();
if( sidTestSMReady != DefaultObjectId &&
!shm->waitSMworking(sidTestSMReady , activateTimeout, 50) )
{
ostringstream err;
err << myname
<< "(askSensors): Не дождались готовности(work) SharedMemory к работе в течение "
<< activateTimeout << " мсек";
iocrit << err.str() << endl;
// kill(SIGTERM, getpid()); // прерываем (перезапускаем) процесс...
std::terminate();
// throw SystemError(err.str());
}
PassiveTimer ptAct(activateTimeout);
while( !readconf_ok && !ptAct.checkTime() )
......@@ -1643,15 +1623,17 @@ namespace uniset
// -----------------------------------------------------------------------------
void IOControl::waitSM()
{
if( !shm->waitSMready(smReadyTimeout, 50) )
if( !shm->waitSMreadyWithCancellation(smReadyTimeout, cancelled, 50) )
{
ostringstream err;
err << myname << "(execute): did not wait for the ready 'SharedMemory'. Timeout "
<< smReadyTimeout << " msec";
if( !cancelled )
{
ostringstream err;
err << myname << "(execute): did not wait for the ready 'SharedMemory'. Timeout "
<< smReadyTimeout << " msec";
iocrit << err.str() << endl;
//throw SystemError(err.str());
std::terminate();
iocrit << err.str() << endl;
std::terminate();
}
}
}
// -----------------------------------------------------------------------------
......
......@@ -33,7 +33,6 @@
#include "DigitalFilter.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SingleProcess.h"
#include "IOController.h"
#include "IOBase.h"
#include "SharedMemory.h"
......@@ -328,7 +327,6 @@ namespace uniset
virtual void askSensors( UniversalIO::UIOCommand cmd );
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sigterm( int signo ) override;
virtual bool activateObject() override;
virtual bool deactivateObject() override;
......@@ -409,10 +407,10 @@ namespace uniset
std::mutex iopollMutex;
std::atomic_bool activated = { false };
std::atomic_bool cancelled = { false };
bool readconf_ok = { false };
int activateTimeout;
uniset::ObjectId sidTestSMReady = { uniset::DefaultObjectId };
std::atomic_bool term = { false };
uniset::ObjectId testMode_as = { uniset::DefaultObjectId };
IOController::IOStateList::iterator itTestMode;
......
......@@ -148,7 +148,7 @@ void PassiveLProcessor::sysCommand( const uniset::SystemMessage* sm )
{
case SystemMessage::StartUp:
{
if( !shm->waitSMready(smReadyTimeout) )
if( !shm->waitSMreadyWithCancellation(smReadyTimeout,cannceled) )
{
dcrit << myname << "(ERR): SM not ready. Terminated... " << endl;
std::terminate();
......@@ -222,46 +222,46 @@ bool PassiveLProcessor::activateObject()
return true;
}
// ------------------------------------------------------------------------------------------
void PassiveLProcessor::initIterators()
{
shm->initIterator(itHeartBeat);
}
// -------------------------------------------------------------------------
void PassiveLProcessor::setOuts()
bool PassiveLProcessor::deactivateObject()
{
// выcтавляем выходы
for( auto && it : extOuts )
cannceled = true;
for( const auto& it : extOuts )
{
try
{
shm->setValue( it.sid, it.el->getOut() );
}
catch( const uniset::Exception& ex )
{
dcrit << myname << "(setOuts): " << ex << endl;
shm->setValue(it.sid, 0);
}
catch( const std::exception& ex )
{
dcrit << myname << "(setOuts): catch: " << ex.what() << endl;
dcrit << myname << "(sigterm): catch:" << ex.what() << endl;
}
}
return UniSetObject::deactivateObject();
}
// ------------------------------------------------------------------------------------------
void PassiveLProcessor::initIterators()
{
shm->initIterator(itHeartBeat);
}
// -------------------------------------------------------------------------
void PassiveLProcessor::sigterm( int signo )
void PassiveLProcessor::setOuts()
{
// выcтавляем выходы
for( auto && it : extOuts )
{
try
{
shm->setValue(it.sid, 0);
shm->setValue( it.sid, it.el->getOut() );
}
catch( const uniset::Exception& ex )
{
dcrit << myname << "(sigterm): " << ex << endl;
dcrit << myname << "(setOuts): " << ex << endl;
}
catch( const std::exception& ex )
{
dcrit << myname << "(sigterm): catch:" << ex.what() << endl;
dcrit << myname << "(setOuts): catch: " << ex.what() << endl;
}
}
}
......
......@@ -65,10 +65,9 @@ namespace uniset
void askSensors( const UniversalIO::UIOCommand cmd );
// void initOutput();
// действия при завершении работы
virtual void sigterm( int signo ) override;
void initIterators();
virtual bool activateObject() override;
virtual bool deactivateObject() override;
std::shared_ptr<SMInterface> shm;
......@@ -78,6 +77,7 @@ namespace uniset
int maxHeartBeat = { 10 };
IOController::IOStateList::iterator itHeartBeat;
std::mutex mutex_start;
std::atomic_bool cannceled = { false };
};
// --------------------------------------------------------------------------
} // end of namespace uniset
......
......@@ -139,14 +139,6 @@ MQTTPublisher::~MQTTPublisher()
mosqpp::lib_cleanup(); // Mosquitto library cleanup
}
// -----------------------------------------------------------------------------
void MQTTPublisher::sigterm(int signo )
{
myinfo << myname << "(sigterm): signo=" << signo << endl;
disconnect();
connectOK = false;
UObject_SK::sigterm(signo);
}
//--------------------------------------------------------------------------------
bool MQTTPublisher::deactivateObject()
{
myinfo << myname << "(deactivateObject): ...disconnect.." << endl;
......
......@@ -129,7 +129,6 @@ namespace uniset
virtual void askSensors( UniversalIO::UIOCommand cmd ) override;
virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
virtual void sigterm( int signo ) override;
virtual bool deactivateObject() override;
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
......
......@@ -311,12 +311,15 @@ namespace uniset
else if( tout < 0 )
ready_timeout = UniSetTimer::WaitUpTime;
if( !shm->waitSMready(ready_timeout, 50) )
if( !shm->waitSMreadyWithCancellation(ready_timeout, canceled, 50) )
{
ostringstream err;
err << myname << "(waitSMReady): failed waiting SharedMemory " << ready_timeout << " msec. ==> TERMINATE!";
mbcrit << err.str() << endl;
std::terminate();
if( !canceled )
{
ostringstream err;
err << myname << "(waitSMReady): failed waiting SharedMemory " << ready_timeout << " msec. ==> TERMINATE!";
mbcrit << err.str() << endl;
std::terminate();
}
}
}
// -----------------------------------------------------------------------------
......@@ -353,24 +356,11 @@ namespace uniset
activated = st;
}
// -----------------------------------------------------------------------------
void MBExchange::sigterm( int signo )
bool MBExchange::deactivateObject()
{
mbwarn << myname << ": ********* SIGTERM(" << signo << ") ********" << endl;
setProcActive(false);
try
{
UniSetObject::sigterm(signo);
}
catch( std::exception& ex)
{
mbwarn << myname << "SIGTERM(" << signo << "): " << ex.what() << endl;
}
// {
// std::exception_ptr p = std::current_exception();
// std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
// }
canceled = true;
return UniSetObject::deactivateObject();
}
// ------------------------------------------------------------------------------------------
void MBExchange::readConfiguration()
......
......@@ -253,7 +253,7 @@ namespace uniset
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd );
virtual void initOutput();
virtual void sigterm( int signo ) override;
virtual bool deactivateObject() override;
virtual bool activateObject() override;
virtual void initIterators();
virtual void initValues();
......@@ -355,6 +355,7 @@ namespace uniset
long exchangeMode = { emNone }; /*!< режим работы см. ExchangeMode */
std::atomic_bool activated = { false };
std::atomic_bool canceled = { false };
timeout_t activateTimeout = { 20000 }; // msec
bool noQueryOptimization = { false };
bool notUseExchangeTimer = { false };
......
......@@ -189,33 +189,6 @@ void MBTCPMaster::poll_thread()
}
}
// -----------------------------------------------------------------------------
void MBTCPMaster::sigterm( int signo )
{
setProcActive(false);
if( pollThread )
{
pollThread->stop();
if( pollThread->isRunning() )
pollThread->join();
}
try
{
MBExchange::sigterm(signo);
}
catch( const std::exception& ex )
{
cerr << "catch: " << ex.what() << endl;
}
catch( ... )
{
std::exception_ptr p = std::current_exception();
std::clog << (p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
}
// -----------------------------------------------------------------------------
bool MBTCPMaster::deactivateObject()
{
setProcActive(false);
......
......@@ -266,7 +266,6 @@ namespace uniset
protected:
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) override;
virtual void sigterm( int signo ) override;
virtual bool deactivateObject() override;
std::string iaddr;
......
......@@ -587,40 +587,6 @@ void MBTCPMultiMaster::initIterators()
shm->initIterator(it->respond_it);
}
// -----------------------------------------------------------------------------
void MBTCPMultiMaster::sigterm( int signo )
{
if( pollThread )
{
pollThread->stop();
if( pollThread->isRunning() )
pollThread->join();
}
if( checkThread )
{
checkThread->stop();
if( checkThread->isRunning() )
checkThread->join();
}
try
{
MBExchange::sigterm(signo);
}
catch( const std::exception& ex )
{
mbcrit << myname << "(sigterm): " << ex.what() << std::endl;
}
// catch( ... )
// {
// std::exception_ptr p = std::current_exception();
// std::clog << (p ? p.__cxa_exception_type()->name() : "null") << std::endl;
// }
}
// -----------------------------------------------------------------------------
bool MBTCPMultiMaster::deactivateObject()
{
setProcActive(false);
......
......@@ -305,7 +305,6 @@ namespace uniset
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void initIterators() override;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) override;
virtual void sigterm( int signo ) override;
virtual bool deactivateObject() override;
void initCheckConnectionParameters();
......
......@@ -548,13 +548,16 @@ namespace uniset
else if( tout < 0 )
ready_timeout = UniSetTimer::WaitUpTime;
if( !shm->waitSMready(ready_timeout, 50) )
if( !shm->waitSMreadyWithCancellation(ready_timeout, cancelled, 50) )
{
ostringstream err;
err << myname << "(waitSMReady): Не дождались готовности SharedMemory к работе в течение " << ready_timeout << " мсек";
mbcrit << err.str() << endl;
//terminate();
std::terminate();
if( !cancelled )
{
ostringstream err;
err << myname << "(waitSMReady): Не дождались готовности SharedMemory к работе в течение " << ready_timeout << " мсек";
mbcrit << err.str() << endl;
//terminate();
std::terminate();
}
}
}
// -----------------------------------------------------------------------------
......@@ -1156,41 +1159,8 @@ namespace uniset
activated = false;
cancelled = true;
if( mbtype == "RTU" )
{
try
{
if( mbslot )
mbslot->sigterm(SIGTERM);
}
catch( std::exception& ex)
{
mbwarn << myname << "(deactivateObject): " << ex.what() << endl;
}
}
return UniSetObject::deactivateObject();
}
// ------------------------------------------------------------------------------------------
void MBSlave::sigterm( int signo )
{
mbinfo << myname << ": ********* SIGTERM(" << signo << ") ********" << endl;
if( cancelled )
{
UniSetObject::sigterm(signo);
return;
}
activated = false;
cancelled = true;
if( tcpserver )
{
cancelled = true;
cerr << "********* MBSlave::sigterm" << endl;
if( tcpserver->isActive() )
tcpserver->terminate();
}
......@@ -1199,15 +1169,15 @@ namespace uniset
try
{
if( mbslot )
mbslot->sigterm(signo);
mbslot->terminate();
}
catch( std::exception& ex)
{
mbwarn << myname << "SIGTERM(" << signo << "): " << ex.what() << endl;
mbwarn << myname << "(deactivateObject): " << ex.what() << endl;
}
}
UniSetObject::sigterm(signo);
return UniSetObject::deactivateObject();
}
// ------------------------------------------------------------------------------------------
void MBSlave::readConfiguration()
......
......@@ -515,7 +515,6 @@ namespace uniset
virtual bool deactivateObject() override;
// действия при завершении работы
virtual void sigterm( int signo ) override;
virtual void finalThread();
enum Timer
......
......@@ -310,6 +310,9 @@ namespace uniset
if( logserv && logserv->isRunning() )
logserv->terminate();
if( wdt )
wdt->stop();
return IONotifyController::deactivateObject();
}
// ------------------------------------------------------------------------------------------
......@@ -367,19 +370,6 @@ namespace uniset
return workready;
}
// ------------------------------------------------------------------------------------------
void SharedMemory::sigterm( int signo )
{
workready = false;
if( signo == SIGTERM && wdt )
wdt->stop();
if( logserv && logserv->isRunning() )
logserv->terminate();
IONotifyController::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
void SharedMemory::checkHeartBeat()
{
if( hblist.empty() )
......
......@@ -435,8 +435,6 @@ namespace uniset
void initFromReserv();
bool initFromSM( uniset::ObjectId sm_id, uniset::ObjectId sm_node );
// действия при завершении работы
virtual void sigterm( int signo ) override;
virtual bool activateObject() override;
virtual bool deactivateObject() override;
bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec );
......
......@@ -487,12 +487,15 @@ void UNetExchange::waitSMReady()
else if( tout < 0 )
ready_timeout = UniSetTimer::WaitUpTime;
if( !shm->waitSMready(ready_timeout, 50) )
if( !shm->waitSMreadyWithCancellation(ready_timeout, cannceled, 50) )
{
ostringstream err;
err << myname << "(waitSMReady): Не дождались готовности SharedMemory к работе в течение " << ready_timeout << " мсек";
unetcrit << err.str() << endl;
std::terminate();
if( !cannceled )
{
ostringstream err;
err << myname << "(waitSMReady): Не дождались готовности SharedMemory к работе в течение " << ready_timeout << " мсек";
unetcrit << err.str() << endl;
std::terminate();
}
}
}
// -----------------------------------------------------------------------------
......@@ -733,6 +736,7 @@ bool UNetExchange::activateObject()
// ------------------------------------------------------------------------------------------
bool UNetExchange::deactivateObject()
{
cannceled = true;
if( activated )
{
unetinfo << myname << "(deactivateObject): disactivate.." << endl;
......@@ -781,17 +785,6 @@ void UNetExchange::termSenders()
catch(...) {}
}
// ------------------------------------------------------------------------------------------
void UNetExchange::sigterm( int signo )
{
unetinfo << myname << ": ********* SIGTERM(" << signo << ") ********" << endl;
activated = false;
termReceivers();
termSenders();
UniSetObject::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
void UNetExchange::initIterators() noexcept
{
shm->initIterator(itHeartBeat);
......
......@@ -169,7 +169,6 @@ namespace uniset
virtual bool deactivateObject() override;
// действия при завершении работы
virtual void sigterm( int signo );
void termSenders();
void termReceivers();
......@@ -195,6 +194,7 @@ namespace uniset
timeout_t steptime = { 1000 }; /*!< периодичность вызова step, [мсек] */
std::atomic_bool activated = { false };
std::atomic_bool cannceled = { false };
timeout_t activateTimeout = { 20000 }; // msec
struct ReceiverInfo
......
......@@ -145,7 +145,7 @@ UniExchange::~UniExchange()
// -----------------------------------------------------------------------------
void UniExchange::execute()
{
if( !shm->waitSMready(smReadyTimeout, 50) )
if( !shm->waitSMreadyWithCancellation(smReadyTimeout, canncelled, 50) )
{
ostringstream err;
err << myname << "(execute): Не дождались готовности SharedMemory к работе в течение "
......@@ -328,6 +328,12 @@ void UniExchange::askSensors( UniversalIO::UIOCommand cmd )
}
// -----------------------------------------------------------------------------
bool UniExchange::deactivateObject()
{
canncelled = true;
return IOController::deactivateObject();
}
// -----------------------------------------------------------------------------
void UniExchange::sysCommand( const SystemMessage* sm )
{
switch( sm->command )
......@@ -352,10 +358,6 @@ void UniExchange::sysCommand( const SystemMessage* sm )
}
}
// -----------------------------------------------------------------------------
void UniExchange::sigterm( int signo )
{
}
// -----------------------------------------------------------------------------
std::shared_ptr<UniExchange> UniExchange::init_exchange(int argc, const char* const* argv,
uniset::ObjectId icID, const std::shared_ptr<SharedMemory>& ic,
const std::string& prefix )
......
......@@ -74,7 +74,7 @@ namespace uniset
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void askSensors( UniversalIO::UIOCommand cmd );
virtual void sigterm( int signo ) override;
virtual bool deactivateObject() override;
xmlNode* cnode = { 0 };
std::string s_field = { "" };
......@@ -144,6 +144,8 @@ namespace uniset
size_t maxIndex = { 0 };
timeout_t smReadyTimeout = { 60000 }; // msec
std::atomic_bool canncelled = { false };
private:
};
// --------------------------------------------------------------------------
......
......@@ -19,6 +19,7 @@
//--------------------------------------------------------------------------
#include <string>
#include <memory>
#include <atomic>
#include "UniSetTypes.h"
#include "Mutex.h"
#include "IONotifyController.h"
......@@ -67,6 +68,7 @@ namespace uniset
bool exist();
bool waitSMready( int msec, int pause = 5000 );
bool waitSMworking( uniset::ObjectId, int msec, int pause = 3000 );
bool waitSMreadyWithCancellation( int msec, std::atomic_bool& cancelFlag, int pause = 5000 );
inline bool isLocalwork() const noexcept
{
......
/*
* Copyright (c) 2015 Pavel Vainerman.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 2.1.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// --------------------------------------------------------------------------
#ifndef SingleProcess_H_
#define SingleProcess_H_
// --------------------------------------------------------------------------
#include <string>
// --------------------------------------------------------------------------
namespace uniset
{
// --------------------------------------------------------------------------
/*! Базовый класс для одиночных процессов.
Обеспечивает корректное завершение процесса,
даже по сигналам...
*/
class SingleProcess
{
public:
SingleProcess();
virtual ~SingleProcess();
protected:
virtual void term( int signo ) {}
static void set_signals( bool ask );
private:
static void terminated( int signo );
static void finishterm( int signo );
};
// --------------------------------------------------------------------------
} // end of namespace uniset
// --------------------------------------------------------------------------
#endif // SingleProcess_H_
// --------------------------------------------------------------------------
......@@ -5,7 +5,7 @@ lib_LTLIBRARIES = libUniSet2Extensions.la
libUniSet2Extensions_la_LDFLAGS = -version-info $(UEXT_VER)
libUniSet2Extensions_la_CPPFLAGS = $(SIGC_CFLAGS) $(POCO_CFLAGS) -I$(top_builddir)/extensions/include
libUniSet2Extensions_la_LIBADD = $(SIGC_LIBS) $(POCO_LIBS) $(top_builddir)/lib/libUniSet2.la
libUniSet2Extensions_la_SOURCES = Extensions.cc SMInterface.cc Calibration.cc SingleProcess.cc \
libUniSet2Extensions_la_SOURCES = Extensions.cc SMInterface.cc Calibration.cc \
IOBase.cc DigitalFilter.cc PID.cc MTR.cc VTypes.cc UObject_SK.cc
UObject_SK.cc: $(top_builddir)/Utilities/codegen/*.xsl
......
......@@ -273,17 +273,22 @@ using namespace uniset;
// --------------------------------------------------------------------------
bool SMInterface::waitSMready( int ready_timeout, int pmsec )
{
PassiveTimer ptSMready(ready_timeout);
std::atomic_bool cancelFlag = { false };
return waitSMreadyWithCancellation(ready_timeout,cancelFlag,pmsec);
}
// --------------------------------------------------------------------------
bool SMInterface::waitSMworking( uniset::ObjectId sid, int msec, int pmsec )
{
PassiveTimer ptSMready(msec);
bool sm_ready = false;
while( !ptSMready.checkTime() && !sm_ready )
{
try
{
sm_ready = exist();
if( sm_ready )
break;
getValue(sid);
sm_ready = true;
break;
}
catch(...) {}
......@@ -293,18 +298,19 @@ using namespace uniset;
return sm_ready;
}
// --------------------------------------------------------------------------
bool SMInterface::waitSMworking( uniset::ObjectId sid, int msec, int pmsec )
bool SMInterface::waitSMreadyWithCancellation(int ready_timeout, std::atomic_bool& cancelFlag, int pmsec)
{
PassiveTimer ptSMready(msec);
PassiveTimer ptSMready(ready_timeout);
bool sm_ready = false;
while( !ptSMready.checkTime() && !sm_ready )
while( !ptSMready.checkTime() && !sm_ready && !cancelFlag )
{
try
{
getValue(sid);
sm_ready = true;
break;
sm_ready = exist();
if( sm_ready )
break;
}
catch(...) {}
......
/*
* Copyright (c) 2015 Pavel Vainerman.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 2.1.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// -------------------------------------------------------------------------
#include <atomic>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <iostream>
#include "SingleProcess.h"
// --------------------------------------------------------------------------
namespace uniset
{
// --------------------------------------------------------------------------------
using namespace std;
// --------------------------------------------------------------------------------
/*! замок для блокирования совместного доступа к функции обрабтки сигналов */
static std::atomic_bool procterm;
static std::atomic_bool doneterm;
static SingleProcess* gMain = NULL;
static const int TERMINATE_TIMEOUT = 2; // время отведенное на завершение процесса [сек]
// --------------------------------------------------------------------------------
SingleProcess::SingleProcess()
{
gMain = this;
}
// --------------------------------------------------------------------------------
SingleProcess::~SingleProcess()
{
}
// --------------------------------------------------------------------------------
void SingleProcess::finishterm( int signo )
{
if( !doneterm )
{
cerr << "(SingleProcess:finishterm): прерываем процесс завершения...!" << endl << flush;
sigset(SIGALRM, SIG_DFL);
gMain->set_signals(false);
doneterm = 1;
raise(SIGKILL);
}
}
// ------------------------------------------------------------------------------------------
void SingleProcess::terminated( int signo )
{
if( !signo || doneterm || !gMain || procterm )
return;
{
// lock
// на случай прихода нескольких сигналов
if( !procterm )
{
procterm = 1;
sighold(SIGALRM);
sigset(SIGALRM, SingleProcess::finishterm);
alarm(TERMINATE_TIMEOUT);
sigrelse(SIGALRM);
gMain->term(signo);
gMain->set_signals(false);
doneterm = 1;
raise(signo);
}
}
}
// --------------------------------------------------------------------------------
void SingleProcess::set_signals( bool ask )
{
struct sigaction act, oact;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESETHAND;
// добавляем сигналы, которые будут игнорироваться
// при обработке сигнала
sigaddset(&act.sa_mask, SIGINT);
sigaddset(&act.sa_mask, SIGTERM);
sigaddset(&act.sa_mask, SIGABRT );
sigaddset(&act.sa_mask, SIGQUIT);
// sigaddset(&act.sa_mask, SIGSEGV);
// sigaddset(&act.sa_mask, SIGALRM);
// act.sa_flags = 0;
// act.sa_flags |= SA_RESTART;
// act.sa_flags |= SA_RESETHAND;
if(ask)
act.sa_handler = terminated;
else
act.sa_handler = SIG_DFL;
sigaction(SIGINT, &act, &oact);
sigaction(SIGTERM, &act, &oact);
sigaction(SIGABRT, &act, &oact);
sigaction(SIGQUIT, &act, &oact);
// sigaction(SIGSEGV, &act, &oact);
}
// --------------------------------------------------------------------------------
} // end of namespace uniset
......@@ -37,7 +37,6 @@ namespace uniset
virtual void sysCommand( const uniset::SystemMessage* sm ) override;
virtual void sensorInfo( const uniset::SensorMessage* si ) override;
virtual void timerInfo( const uniset::TimerMessage* tm ) override;
virtual void sigterm( int signo ) override;
SMonitor();
private:
......
......@@ -24,6 +24,7 @@
// ---------------------------------------------------------------------------
#include <memory>
#include <string>
#include <atomic>
#include <sstream>
#include <unordered_map>
#include <functional>
......@@ -182,14 +183,17 @@ namespace uniset
bool isExist( const uniset::ObjectId id ) const noexcept;
bool isExist( const uniset::ObjectId id, const uniset::ObjectId node ) const noexcept;
// used for check 'isExist'
//! used for check 'isExist' \deprecated! Use waitReadyWithCancellation(..)
bool waitReady( const uniset::ObjectId id, int msec, int pause = 5000,
const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() ) noexcept;
// used for check 'getValue'
//! used for check 'getValue'
bool waitWorking( const uniset::ObjectId id, int msec, int pause = 3000,
const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() ) noexcept;
bool waitReadyWithCancellation( const uniset::ObjectId id, int msec, std::atomic_bool& cancelFlag, int pause = 5000,
const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() ) noexcept;
// ---------------------------------------------------------------
// Работа с ID, Name
......
......@@ -100,6 +100,7 @@ namespace uniset
private:
void init();
static void on_finish_timeout();
static void evsignal( ev::sig& signal, int signo );
virtual void evprepare() override;
virtual void evfinish() override;
......
......@@ -93,7 +93,7 @@ namespace uniset
virtual bool addObject( const std::shared_ptr<UniSetObject>& obj );
virtual bool removeObject( const std::shared_ptr<UniSetObject>& obj );
enum OManagerCommand { deactiv, activ, initial, term };
enum OManagerCommand { deactiv, activ, initial };
friend std::ostream& operator<<(std::ostream& os, uniset::UniSetManager::OManagerCommand& cmd );
// работа со списком объектов
......@@ -101,8 +101,6 @@ namespace uniset
// работа со списком менеджеров
void managers(OManagerCommand cmd);
virtual void sigterm( int signo ) override;
void initPOA( const std::weak_ptr<UniSetManager>& rmngr );
//! \note Переопределяя не забывайте вызвать базовую
......
......@@ -157,17 +157,10 @@ namespace uniset
//! Активизация объекта (переопределяется для необходимых действий после активизации)
virtual bool activateObject();
//! Деактивиция объекта (переопределяется для необходимых действий перед деактивацией)
//! Деактивиция объекта (переопределяется для необходимых действий при завершении работы)
virtual bool deactivateObject();
/*! Функция вызываемая при приходе сигнала завершения или прерывания процесса. Переопределив ее можно
* выполнять специфичные для процесса действия по обработке сигнала.
* Например переход в безопасное состояние.
* \warning В обработчике сигналов \b ЗАПРЕЩЕНО вызывать функции подобные exit(..), abort()!!!!
*/
virtual void sigterm( int signo );
void terminate();
// void terminate();
// управление созданием потока обработки сообщений -------
......
......@@ -24,7 +24,7 @@ namespace uniset
ModbusRTUSlaveSlot( const std::string& dev, bool use485 = false, bool tr_ctl = false );
virtual ~ModbusRTUSlaveSlot();
virtual void sigterm( int signo );
virtual void terminate();
inline ComPort* getComPort()
{
......
......@@ -114,7 +114,7 @@ namespace uniset
/*! подключение обработчика 'передача файла' 0x66 */
void connectFileTransfer( FileTransferSlot sl );
virtual void sigterm( int signo ) {}
virtual void terminate(){}
protected:
ReadCoilSlot slReadCoil;
......
......@@ -18,7 +18,7 @@ namespace uniset
ModbusTCPServerSlot( const std::string& ia, int port = 502 );
virtual ~ModbusTCPServerSlot();
virtual void sigterm( int signo );
virtual void terminate() override;
protected:
......
......@@ -174,7 +174,7 @@ namespace uniset
return slFileTransfer(query, reply);
}
// -------------------------------------------------------------------------
void ModbusRTUSlaveSlot::sigterm( int signo )
void ModbusRTUSlaveSlot::terminate()
{
try
{
......
......@@ -168,11 +168,11 @@ namespace uniset
return slFileTransfer(query, reply);
}
// -------------------------------------------------------------------------
void ModbusTCPServerSlot::sigterm( int signo )
void ModbusTCPServerSlot::terminate()
{
try
{
terminate();
ModbusTCPServer::terminate();
}
catch( std::exception& ex ) {}
}
......
......@@ -2375,6 +2375,12 @@ namespace uniset
// -----------------------------------------------------------------------------
bool UInterface::waitReady( const uniset::ObjectId id, int msec, int pmsec, const uniset::ObjectId node ) noexcept
{
std::atomic_bool cancelFlag = { false };
return waitReadyWithCancellation(id,msec,cancelFlag,pmsec,node);
}
// -----------------------------------------------------------------------------
bool UInterface::waitWorking( const uniset::ObjectId id, int msec, int pmsec, const uniset::ObjectId node ) noexcept
{
if( msec < 0 )
msec = 0;
......@@ -2388,21 +2394,11 @@ namespace uniset
{
try
{
ready = isExist(id, node);
if( ready )
break;
}
catch( const CORBA::OBJECT_NOT_EXIST& )
{
}
catch( const CORBA::COMM_FAILURE& ex )
{
}
catch(...)
{
getValue(id, node);
ready = true;
break;
}
catch(...) {}
msleep(pmsec);
}
......@@ -2410,7 +2406,8 @@ namespace uniset
return ready;
}
// -----------------------------------------------------------------------------
bool UInterface::waitWorking( const uniset::ObjectId id, int msec, int pmsec, const uniset::ObjectId node ) noexcept
bool UInterface::waitReadyWithCancellation(const ObjectId id, int msec,
std::atomic_bool& cancelFlag, int pmsec, const ObjectId node) noexcept
{
if( msec < 0 )
msec = 0;
......@@ -2421,15 +2418,25 @@ namespace uniset
PassiveTimer ptReady(msec);
bool ready = false;
while( !ptReady.checkTime() && !ready )
while( !ptReady.checkTime() && !ready && !cancelFlag )
{
try
{
getValue(id, node);
ready = true;
ready = isExist(id, node);
if( ready )
break;
}
catch( const CORBA::OBJECT_NOT_EXIST& )
{
}
catch( const CORBA::COMM_FAILURE& ex )
{
}
catch(...)
{
break;
}
catch(...) {}
msleep(pmsec);
}
......
......@@ -18,9 +18,6 @@
* \author Pavel Vainerman
*/
// --------------------------------------------------------------------------
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <sstream>
#include <fstream>
......@@ -32,9 +29,9 @@
// for stack trace
// --------------------
#include <execinfo.h>
#include <cxxabi.h>
#include <dlfcn.h>
//#include <execinfo.h>
//#include <cxxabi.h>
//#include <dlfcn.h>
#include <iomanip>
// --------------------
......@@ -50,6 +47,13 @@
using namespace uniset;
using namespace std;
// ------------------------------------------------------------------------------------------
static std::mutex g_donemutex;
static std::condition_variable g_doneevent;
static std::shared_ptr<std::thread> g_finish_guard_thread;
static std::atomic_bool g_done = ATOMIC_VAR_INIT(0);
static const int TERMINATE_TIMEOUT_SEC = 15; // время отведенное на завершение процесса [сек]
// ------------------------------------------------------------------------------------------
namespace uniset
{
UniSetActivatorPtr UniSetActivator::inst;
......@@ -104,11 +108,11 @@ void UniSetActivator::init()
sigTERM.set(loop);
sigINT.set(loop);
sigABRT.set(loop);
// sigABRT.set(loop);
sigQUIT.set(loop);
sigINT.set<&UniSetActivator::evsignal>();
sigTERM.set<&UniSetActivator::evsignal>();
sigABRT.set<&UniSetActivator::evsignal>();
// sigABRT.set<&UniSetActivator::evsignal>();
sigQUIT.set<&UniSetActivator::evsignal>();
}
......@@ -191,6 +195,13 @@ void UniSetActivator::stop()
active = false;
{
std::unique_lock<std::mutex> lk(g_donemutex);
g_done = false;
g_finish_guard_thread = make_shared<std::thread>(on_finish_timeout);
}
ulogsys << myname << "(stop): deactivate... " << endl;
deactivate();
......@@ -236,6 +247,16 @@ void UniSetActivator::stop()
if( orbthr )
orbthr->join();
{
std::unique_lock<std::mutex> lk(g_donemutex);
g_done = true;
}
g_doneevent.notify_all();
if( g_finish_guard_thread )
g_finish_guard_thread->join();
}
// ------------------------------------------------------------------------------------------
......@@ -293,6 +314,33 @@ void UniSetActivator::work()
ulogsys << myname << "(work): orb thread stopped!" << endl << flush;
}
// ------------------------------------------------------------------------------------------
void UniSetActivator::on_finish_timeout()
{
std::unique_lock<std::mutex> lk(g_donemutex);
if( g_done )
return;
ulogsys << "(FINISH GUARD THREAD): activate... " << endl << flush;
g_doneevent.wait_for(lk, std::chrono::milliseconds(TERMINATE_TIMEOUT_SEC * 1000), []()
{
return (g_done == true);
} );
if( !g_done )
{
ulogsys << "(FINISH GUARD THREAD): WAIT TIMEOUT "
<< TERMINATE_TIMEOUT_SEC << " sec..KILL *******" << endl << flush;
//raise(SIGKILL);
std::abort();
return;
}
ulogsys << "(FINISH GUARD THREAD): [OK]..bye.." << endl;
}
// ------------------------------------------------------------------------------------------
#ifndef DISABLE_REST_API
Poco::JSON::Object::Ptr UniSetActivator::httpGetByName( const string& name, const Poco::URI::QueryParameters& p )
{
......
......@@ -266,10 +266,6 @@ void UniSetManager::managers( OManagerCommand cmd )
li->deactivate();
break;
case term:
li->sigterm(sig);
break;
default:
break;
}
......@@ -369,10 +365,6 @@ void UniSetManager::objects(OManagerCommand cmd)
li->deactivate();
break;
case term:
li->sigterm(sig);
break;
default:
break;
}
......@@ -542,26 +534,6 @@ void UniSetManager::getAllObjectsList( std::vector<std::shared_ptr<UniSetObject>
}
}
// ------------------------------------------------------------------------------------------
void UniSetManager::sigterm( int signo )
{
sig = signo;
try
{
objects(term);
}
catch(...) {}
try
{
managers(term);
}
catch(...) {}
UniSetObject::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
void UniSetManager::broadcast(const TransportMessage& msg)
{
// себя не забыть...
......@@ -779,8 +751,5 @@ std::ostream& uniset::operator<<(std::ostream& os, uniset::UniSetManager::OManag
if( cmd == uniset::UniSetManager::initial )
return os << "init";
if( cmd == uniset::UniSetManager::term )
return os << "terminate";
return os << "unkwnown";
}
......@@ -550,14 +550,10 @@ namespace uniset
return true;
}
// ------------------------------------------------------------------------------------------
void UniSetObject::sigterm( int signo )
{
}
// ------------------------------------------------------------------------------------------
void UniSetObject::terminate()
{
deactivate();
}
// void UniSetObject::terminate()
// {
// deactivate();
// }
// ------------------------------------------------------------------------------------------
void UniSetObject::thread(bool create)
{
......@@ -595,18 +591,6 @@ namespace uniset
if( tmr )
tmr->terminate();
if( thr )
{
std::unique_lock<std::mutex> lk(m_working);
// cv_working.wait_for(lk, std::chrono::milliseconds(workingTerminateTimeout), [&](){ return (a_working == false); } );
if( a_working )
cv_working.wait(lk);
if( a_working )
thr->stop();
}
try
{
uinfo << myname << "(deactivate): ..." << endl;
......@@ -660,6 +644,18 @@ namespace uniset
}
if( thr )
{
std::unique_lock<std::mutex> lk(m_working);
// cv_working.wait_for(lk, std::chrono::milliseconds(workingTerminateTimeout), [&](){ return (a_working == false); } );
if( a_working )
cv_working.wait(lk);
if( a_working )
thr->stop();
}
return false;
}
......
......@@ -50,11 +50,6 @@ SMonitor::~SMonitor()
{
}
// ------------------------------------------------------------------------------------------
void SMonitor::sigterm( int signo )
{
cout << myname << "SMonitor: sigterm " << endl;
}
// ------------------------------------------------------------------------------------------
void SMonitor::sysCommand( const SystemMessage* sm )
{
switch(sm->command)
......
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