Commit 3be517fb authored by Pavel Vainerman's avatar Pavel Vainerman

(IOController, IONotifyController): рефакторинг работы с userdata,

а также попытка оптимизировать работу с mutex-ами в INC, правки комментариев.
parent 3338255d
...@@ -762,15 +762,10 @@ namespace uniset ...@@ -762,15 +762,10 @@ namespace uniset
if( hist.empty() ) if( hist.empty() )
return; return;
if( usi->userdata[udataHistory] == nullptr ) HistoryItList* lst = static_cast<HistoryItList*>(usi->getUserData(udataHistory));
if( !lst )
return; return;
HistoryItList& lst = *(static_cast<HistoryItList*>(usi->userdata[udataHistory]));
// auto i = histmap.find(s_it->si.id);
// if( i == histmap.end() )
// return;
long value = 0; long value = 0;
unsigned long sm_tv_sec = 0; unsigned long sm_tv_sec = 0;
unsigned long sm_tv_nsec = 0; unsigned long sm_tv_nsec = 0;
...@@ -786,7 +781,7 @@ namespace uniset ...@@ -786,7 +781,7 @@ namespace uniset
<< " value=" << value << " value=" << value
<< endl; << endl;
for( auto && it1 : lst) for( auto&& it1 : (*lst) )
{ {
History::iterator it = it1; History::iterator it = it1;
......
...@@ -33,7 +33,15 @@ ...@@ -33,7 +33,15 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
namespace uniset namespace uniset
{ {
/*! Реализация интерфейса IOController-а */ /*! Реализация интерфейса IOController-а
* Важной особенностью данной реализации является то, что
* список входов/выходов (ioList) формируется один раз во время создания объекта
* и не меняется (!) в процессе работы. На этом построены некоторые оптимизации!
* Поэтому неизменность ioList во время всей жизни объекта должна гарантироваться.
* В частности, очень важной является структура USensorInfo, а также userdata,
* которые используются для "кэширования" (сохранения) указателей на специальные данные.
* (см. также IONotifyContoller).
*/
class IOController: class IOController:
public UniSetManager, public UniSetManager,
public POA_IOController_i public POA_IOController_i
...@@ -298,8 +306,13 @@ namespace uniset ...@@ -298,8 +306,13 @@ namespace uniset
// Дополнительные (вспомогательные поля) // Дополнительные (вспомогательные поля)
uniset::uniset_rwmutex val_lock; /*!< флаг блокирующий работу со значением */ uniset::uniset_rwmutex val_lock; /*!< флаг блокирующий работу со значением */
// userdata (универасльный, небезопасный способ расширения информации связанной с датчиком)
static const size_t MaxUserData = 4; static const size_t MaxUserData = 4;
void* userdata[MaxUserData] = { nullptr, nullptr, nullptr, nullptr }; /*!< расширение для возможности хранения своей информации */ void* userdata[MaxUserData] = { nullptr, nullptr, nullptr, nullptr }; /*!< расширение для возможности хранения своей информации */
uniset::uniset_rwmutex userdata_lock; /*!< mutex для работы с userdata */
void* getUserData( size_t index );
void setUserData( size_t index, void* data );
// сигнал для реализации механизма зависимостией.. // сигнал для реализации механизма зависимостией..
// (все зависимые датчики подключаются к нему (см. NCRestorer::init_depends_signals) // (все зависимые датчики подключаются к нему (см. NCRestorer::init_depends_signals)
...@@ -328,7 +341,7 @@ namespace uniset ...@@ -328,7 +341,7 @@ namespace uniset
return std::move(s); return std::move(s);
} }
inline uniset::SensorMessage makeSensorMessage() inline uniset::SensorMessage makeSensorMessage( bool with_lock = false )
{ {
uniset::SensorMessage sm; uniset::SensorMessage sm;
sm.id = si.id; sm.id = si.id;
...@@ -337,6 +350,7 @@ namespace uniset ...@@ -337,6 +350,7 @@ namespace uniset
sm.priority = (uniset::Message::Priority)priority; sm.priority = (uniset::Message::Priority)priority;
// лочим только изменяемые поля // лочим только изменяемые поля
if( with_lock )
{ {
uniset::uniset_rwmutex_rlock lock(val_lock); uniset::uniset_rwmutex_rlock lock(val_lock);
sm.value = value; sm.value = value;
...@@ -346,6 +360,15 @@ namespace uniset ...@@ -346,6 +360,15 @@ namespace uniset
sm.supplier = supplier; sm.supplier = supplier;
sm.undefined = undefined; sm.undefined = undefined;
} }
else
{
sm.value = value;
sm.sm_tv.tv_sec = tv_sec;
sm.sm_tv.tv_nsec = tv_nsec;
sm.ci = ci;
sm.supplier = supplier;
sm.undefined = undefined;
}
return std::move(sm); return std::move(sm);
} }
......
...@@ -113,20 +113,22 @@ namespace uniset ...@@ -113,20 +113,22 @@ namespace uniset
\section sec_NC_Optimization Оптимизация работы со списком "заказчиков" \section sec_NC_Optimization Оптимизация работы со списком "заказчиков"
Для оптимизации поиска списка заказчиков для конкретного датчика используется поле userdata (void*) у USensorInfo! Для оптимизации поиска списка заказчиков для конкретного датчика используется поле userdata (void*) у USensorInfo!
Это опасный и "некрасивый" хак, но который позволяет избавиться от одного лишнего поиска по unordered_map<SensorID,ConsumerList>. Это опасный и "некрасивый" хак, но он позволяет избавиться от одного лишнего поиска по unordered_map<SensorID,ConsumerList>.
Суть в том что к датчику через usedata мы привязываем указатель на список заказчиков. Сделано через userdata, Суть в том что к датчику через usedata мы привязываем указатель на список заказчиков. Сделано через userdata,
т.к. сам map "хранится" в IOController и IONotifyController не может поменять тип (в текущей реализации по крайней мере). т.к. сам map "хранится" в IOController и IONotifyController не может поменять тип (в текущей реализации по крайней мере).
В userdata задействованы два места (см. UserDataID) для списка заказчиков и для списка порогов. В userdata задействованы два места (см. UserDataID) для списка заказчиков и для списка порогов.
ри этом, чтобы гарантировать корректность работы, cписки заказчиков по тому или иному датчику,
создаются (см. функцию ask()), но никогда не удаляются, даже если остаются пустыми.
Это сделано, чтобы сохранённые указатели в userdata, оставались всегда валидными
(т.к. используются из разных потоков).
*/ */
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/*! \class IONotifyController /*! \class IONotifyController
*
\section AskSensors Заказ датчиков * \section AskSensors Заказ датчиков
* ....
.... * \b ConsumerMaxAttempts - максимальное число неудачных попыток послать сообщение "заказчику".
ConsumerMaxAttempts - максимальное число неудачных * Настраивается в конфигурационном файле. По умолчанию = 5.
попыток послать сообщение "заказчику". Настраивается в
конфигурационном файле. По умолчанию = 5.
*/ */
class IONotifyController: class IONotifyController:
public IOController, public IOController,
...@@ -179,7 +181,7 @@ namespace uniset ...@@ -179,7 +181,7 @@ namespace uniset
ref(ref), attempt(maxAttemtps) {} ref(ref), attempt(maxAttemtps) {}
UniSetObject_i_var ref; UniSetObject_i_var ref;
size_t attempt; size_t attempt = { 10 };
size_t lostEvents = { 0 }; // количество потерянных сообщений (не смогли послать) size_t lostEvents = { 0 }; // количество потерянных сообщений (не смогли послать)
size_t smCount = { 0 }; // количество посланных SensorMessage size_t smCount = { 0 }; // количество посланных SensorMessage
...@@ -283,7 +285,7 @@ namespace uniset ...@@ -283,7 +285,7 @@ namespace uniset
protected: protected:
IONotifyController(); IONotifyController();
virtual bool activateObject() override; virtual bool activateObject() override;
virtual void initItem(std::shared_ptr<USensorInfo>& usi, IOController* ic ); virtual void initItem( std::shared_ptr<USensorInfo>& usi, IOController* ic );
//! посылка информации об изменении состояния датчика (всем или указанному заказчику) //! посылка информации об изменении состояния датчика (всем или указанному заказчику)
virtual void send( ConsumerListInfo& lst, const uniset::SensorMessage& sm, const uniset::ConsumerInfo* ci = nullptr ); virtual void send( ConsumerListInfo& lst, const uniset::SensorMessage& sm, const uniset::ConsumerInfo* ci = nullptr );
...@@ -351,6 +353,7 @@ namespace uniset ...@@ -351,6 +353,7 @@ namespace uniset
/*! добавить новый порог для датчика */ /*! добавить новый порог для датчика */
bool addThreshold(ThresholdExtList& lst, ThresholdInfoExt&& ti, const uniset::ConsumerInfo& ci); bool addThreshold(ThresholdExtList& lst, ThresholdInfoExt&& ti, const uniset::ConsumerInfo& ci);
/*! удалить порог для датчика */ /*! удалить порог для датчика */
bool removeThreshold(ThresholdExtList& lst, ThresholdInfoExt& ti, const uniset::ConsumerInfo& ci); bool removeThreshold(ThresholdExtList& lst, ThresholdInfoExt& ti, const uniset::ConsumerInfo& ci);
...@@ -380,8 +383,6 @@ namespace uniset ...@@ -380,8 +383,6 @@ namespace uniset
/*! map для хранения информации о заказчиках с которыми была потеряна связь /*! map для хранения информации о заказчиках с которыми была потеряна связь
* и которые были удалены из списка заказчиков * и которые были удалены из списка заказчиков
* size_t - количество раз
* ObjectId - id заказчика
*/ */
std::unordered_map<uniset::ObjectId, LostConsumerInfo> lostConsumers; std::unordered_map<uniset::ObjectId, LostConsumerInfo> lostConsumers;
}; };
......
...@@ -620,7 +620,25 @@ IOController::USensorInfo::operator=(IOController_i::SensorIOInfo* r) ...@@ -620,7 +620,25 @@ IOController::USensorInfo::operator=(IOController_i::SensorIOInfo* r)
(*this) = (*r); (*this) = (*r);
return *this; return *this;
} }
// ----------------------------------------------------------------------------------------
void* IOController::USensorInfo::getUserData( size_t index )
{
if( index > MaxUserData )
return nullptr;
uniset::uniset_rwmutex_rlock ulock(userdata_lock);
return userdata[index];
}
void IOController::USensorInfo::setUserData( size_t index, void* data )
{
if( index > MaxUserData )
return;
uniset::uniset_rwmutex_wrlock ulock(userdata_lock);
userdata[index] = data;
}
// ----------------------------------------------------------------------------------------
const IOController::USensorInfo& const IOController::USensorInfo&
IOController::USensorInfo::operator=(const IOController_i::SensorIOInfo& r) IOController::USensorInfo::operator=(const IOController_i::SensorIOInfo& r)
{ {
...@@ -628,7 +646,7 @@ IOController::USensorInfo::operator=(const IOController_i::SensorIOInfo& r) ...@@ -628,7 +646,7 @@ IOController::USensorInfo::operator=(const IOController_i::SensorIOInfo& r)
// any=0; // any=0;
return *this; return *this;
} }
// ----------------------------------------------------------------------------------------
void IOController::USensorInfo::init( const IOController_i::SensorIOInfo& s ) void IOController::USensorInfo::init( const IOController_i::SensorIOInfo& s )
{ {
IOController::USensorInfo r(s); IOController::USensorInfo r(s);
......
...@@ -513,27 +513,25 @@ void IONotifyController::askSensor(const uniset::ObjectId sid, ...@@ -513,27 +513,25 @@ void IONotifyController::askSensor(const uniset::ObjectId sid,
} }
catch( IOController_i::Undefined& ex ) {} catch( IOController_i::Undefined& ex ) {}
// Чтобы не было гонки между текущей функцией (askSensor) {
// и setValue(), которая может происходить параллельно с этой
// держим askIOMutex до конца функции, а также для посылки пользуемся функцией send()...
uniset_rwmutex_wrlock lock(askIOMutex); uniset_rwmutex_wrlock lock(askIOMutex);
ask(askIOList, sid, ci, cmd); ask(askIOList, sid, ci, cmd);
}
auto usi = li->second; auto usi = li->second;
// посылка первый раз состояния // посылка первый раз состояния
if( cmd == UniversalIO::UIONotify || (cmd == UIONotifyFirstNotNull && usi->value) ) if( cmd == UniversalIO::UIONotify || (cmd == UIONotifyFirstNotNull && usi->value) )
{ {
if( usi->userdata[udataConsumerList] != nullptr ) ConsumerListInfo* lst = static_cast<ConsumerListInfo*>(usi->getUserData(udataConsumerList));
if( lst )
{ {
ConsumerListInfo& lst = *(static_cast<ConsumerListInfo*>(usi->userdata[udataConsumerList])); uniset::uniset_rwmutex_rlock lock(usi->val_lock);
SensorMessage smsg( std::move(usi->makeSensorMessage()) ); SensorMessage smsg( std::move(usi->makeSensorMessage(false)) );
send(lst,smsg,&ci); send(*lst,smsg,&ci);
} }
} }
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void IONotifyController::ask( AskMap& askLst, const uniset::ObjectId sid, void IONotifyController::ask( AskMap& askLst, const uniset::ObjectId sid,
const uniset::ConsumerInfo& cons, UniversalIO::UIOCommand cmd) const uniset::ConsumerInfo& cons, UniversalIO::UIOCommand cmd)
...@@ -549,20 +547,25 @@ void IONotifyController::ask( AskMap& askLst, const uniset::ObjectId sid, ...@@ -549,20 +547,25 @@ void IONotifyController::ask( AskMap& askLst, const uniset::ObjectId sid,
{ {
if( askIterator == askLst.end() ) if( askIterator == askLst.end() )
{ {
ConsumerListInfo lst; // создаем новый список ConsumerListInfo newlst; // создаем новый список
addConsumer(lst, cons); addConsumer(newlst, cons);
// более оптимальный способ(при условии вставки первый раз) askLst.emplace(sid, std::move(newlst));
askLst.emplace(sid, std::move(lst));
// т.к. мы делали move
// то теперь надо достучаться до списка..
auto i = askLst.find(sid);
if( i != askLst.end() )
{
try try
{ {
dumpOrdersList(sid, lst); dumpOrdersList(sid, i->second);
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
{ {
uwarn << myname << " не смогли сделать dump: " << ex << endl; uwarn << myname << " не смогли сделать dump: " << ex << endl;
} }
} }
}
else else
{ {
if( addConsumer(askIterator->second, cons) ) if( addConsumer(askIterator->second, cons) )
...@@ -629,13 +632,11 @@ void IONotifyController::ask( AskMap& askLst, const uniset::ObjectId sid, ...@@ -629,13 +632,11 @@ void IONotifyController::ask( AskMap& askLst, const uniset::ObjectId sid,
if( askIterator != askLst.end() ) if( askIterator != askLst.end() )
{ {
//! \warning Оптимизация использует userdata! Это опасно, если кто-то ещё захочет его использовать!
auto s = myiofind(sid); auto s = myiofind(sid);
if( s != myioEnd() ) if( s != myioEnd() )
s->second->userdata[udataConsumerList] = &(askIterator->second); s->second->setUserData(udataConsumerList,&(askIterator->second));
else else
s->second->userdata[udataConsumerList] = nullptr; s->second->setUserData(udataConsumerList,nullptr);
} }
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -658,7 +659,15 @@ long IONotifyController::localSetValue( std::shared_ptr<IOController::USensorInf ...@@ -658,7 +659,15 @@ long IONotifyController::localSetValue( std::shared_ptr<IOController::USensorInf
if( prevValue == curValue ) if( prevValue == curValue )
return curValue; return curValue;
SensorMessage sm(std::move(usi->makeSensorMessage()));
{
// с учётом того, что параллельно с этой функцией может
// выполняться askSensor, то
// посылать сообщение надо "заблокировав" доступ к value...
uniset::uniset_rwmutex_rlock lock(usi->val_lock);
SensorMessage sm(std::move(usi->makeSensorMessage(false)));
try try
{ {
...@@ -667,15 +676,9 @@ long IONotifyController::localSetValue( std::shared_ptr<IOController::USensorInf ...@@ -667,15 +676,9 @@ long IONotifyController::localSetValue( std::shared_ptr<IOController::USensorInf
} }
catch(...) {} catch(...) {}
{ ConsumerListInfo* lst = static_cast<ConsumerListInfo*>(usi->getUserData(udataConsumerList));
uniset_rwmutex_rlock lock(askIOMutex); if( lst )
send(*lst, sm);
//! \warning Оптимизация использует userdata! Это опасно, если кто-то ещё захочет его использовать!
if( usi->userdata[udataConsumerList] != nullptr )
{
ConsumerListInfo& lst = *(static_cast<ConsumerListInfo*>(usi->userdata[udataConsumerList]));
send(lst, sm);
}
} }
// проверка порогов // проверка порогов
...@@ -789,7 +792,7 @@ void IONotifyController::send( ConsumerListInfo& lst, const uniset::SensorMessag ...@@ -789,7 +792,7 @@ void IONotifyController::send( ConsumerListInfo& lst, const uniset::SensorMessag
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
bool IONotifyController::activateObject() bool IONotifyController::activateObject()
{ {
// сперва вычитаем датчиков и заказчиков.. // сперва загружаем датчики и заказчиков..
readDump(); readDump();
// а потом уже собственно активация.. // а потом уже собственно активация..
return IOController::activateObject(); return IOController::activateObject();
...@@ -805,9 +808,8 @@ void IONotifyController::readDump() ...@@ -805,9 +808,8 @@ void IONotifyController::readDump()
catch( const std::exception& ex ) catch( const std::exception& ex )
{ {
// Если дамп не удалось считать, значит что-то не то в configure.xml // Если дамп не удалось считать, значит что-то не то в configure.xml
// и безопаснее "вылететь", чем запустится, но половина датчиков работать не будет // и безопаснее "вылететь", чем запустится, т.к. часть датчиков не будет работать
// как ожидается. // как ожидается.
ucrit << myname << "(IONotifyController::readDump): " << ex.what() << endl; ucrit << myname << "(IONotifyController::readDump): " << ex.what() << endl;
std::terminate(); // std::abort(); std::terminate(); // std::abort();
} }
...@@ -991,15 +993,9 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum ...@@ -991,15 +993,9 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum
it = askTMap.find(sid); it = askTMap.find(sid);
if( li != myioEnd() ) if( li != myioEnd() )
{ li->second->setUserData(udataThresholdList, &(it->second));
//! \warning Оптимизация использует userdata! Это опасно, если кто-то ещё захочет его использовать!
if( it == askTMap.end() )
li->second->userdata[udataThresholdList] = nullptr;
else
li->second->userdata[udataThresholdList] = (void*)(&(it->second));
}
} // unlock } // unlock trshMutex
} }
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
bool IONotifyController::addThreshold( ThresholdExtList& lst, ThresholdInfoExt&& ti, const uniset::ConsumerInfo& ci ) bool IONotifyController::addThreshold( ThresholdExtList& lst, ThresholdInfoExt&& ti, const uniset::ConsumerInfo& ci )
...@@ -1063,24 +1059,17 @@ void IONotifyController::checkThreshold( IOController::IOStateList::iterator& li ...@@ -1063,24 +1059,17 @@ void IONotifyController::checkThreshold( IOController::IOStateList::iterator& li
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
void IONotifyController::checkThreshold( std::shared_ptr<IOController::USensorInfo>& usi, bool send_msg ) void IONotifyController::checkThreshold( std::shared_ptr<IOController::USensorInfo>& usi, bool send_msg )
{ {
// поиск списка порогов
ThresholdsListInfo* ti = nullptr;
{
uniset_rwmutex_rlock lock(trshMutex); uniset_rwmutex_rlock lock(trshMutex);
//! \warning Оптимизация использует userdata! Это опасно, если кто-то ещё захочет его использовать! ThresholdsListInfo* ti = static_cast<ThresholdsListInfo*>(usi->getUserData(udataThresholdList));
if( usi->userdata[udataThresholdList] == nullptr ) if( !ti || ti->list.empty() )
return; return;
//! \warning Оптимизация использует userdata! Это опасно, если кто-то ещё захочет его использовать! // обрабатываем текущее состояние датчика обязательно "залочив" значение..
ti = static_cast<ThresholdsListInfo*>(usi->userdata[udataThresholdList]);
if( ti->list.empty() ) uniset_rwmutex_rlock vlock(usi->val_lock);
return;
}
SensorMessage sm(std::move(usi->makeSensorMessage())); SensorMessage sm(std::move(usi->makeSensorMessage(false)));
// текущее время // текущее время
struct timespec tm = uniset::now_to_timespec(); struct timespec tm = uniset::now_to_timespec();
...@@ -1316,7 +1305,8 @@ IONotifyController_i::ThresholdsListSeq* IONotifyController::getThresholdsList() ...@@ -1316,7 +1305,8 @@ IONotifyController_i::ThresholdsListSeq* IONotifyController::getThresholdsList()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void IONotifyController::onChangeUndefinedState( std::shared_ptr<USensorInfo>& usi, IOController* ic ) void IONotifyController::onChangeUndefinedState( std::shared_ptr<USensorInfo>& usi, IOController* ic )
{ {
SensorMessage sm( std::move(usi->makeSensorMessage()) ); uniset_rwmutex_rlock vlock(usi->val_lock);
SensorMessage sm( std::move(usi->makeSensorMessage(false)) );
try try
{ {
...@@ -1325,17 +1315,9 @@ void IONotifyController::onChangeUndefinedState( std::shared_ptr<USensorInfo>& u ...@@ -1325,17 +1315,9 @@ void IONotifyController::onChangeUndefinedState( std::shared_ptr<USensorInfo>& u
} }
catch(...) {} catch(...) {}
{ ConsumerListInfo* lst = static_cast<ConsumerListInfo*>(usi->getUserData(udataConsumerList));
// lock if( lst )
uniset_rwmutex_rlock lock(askIOMutex); send(*lst, sm);
//! \warning Оптимизация использует userdata! Это опасно, если кто-то ещё захочет его использовать!
if( usi->userdata[udataConsumerList] != nullptr )
{
ConsumerListInfo& lst = *(static_cast<ConsumerListInfo*>(usi->userdata[udataConsumerList]));
send(lst, sm);
}
} // unlock
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -75,7 +75,7 @@ void NCRestorer::addlist( IONotifyController* ic, std::shared_ptr<IOController:: ...@@ -75,7 +75,7 @@ void NCRestorer::addlist( IONotifyController* ic, std::shared_ptr<IOController::
case UniversalIO::AO: case UniversalIO::AO:
{ {
ic->askIOList[inf->si.id] = std::move(lst); ic->askIOList[inf->si.id] = std::move(lst);
inf->userdata[IONotifyController::udataConsumerList] = &(ic->askIOList[inf->si.id]); inf->setUserData(IONotifyController::udataConsumerList, &(ic->askIOList[inf->si.id]) );
break; break;
} }
...@@ -151,29 +151,15 @@ NCRestorer::SInfo& NCRestorer::SInfo::operator=( const IOController_i::SensorIOI ...@@ -151,29 +151,15 @@ NCRestorer::SInfo& NCRestorer::SInfo::operator=( const IOController_i::SensorIOI
this->blocked = inf.blocked; this->blocked = inf.blocked;
this->dbignore = inf.dbignore; this->dbignore = inf.dbignore;
{
uniset_rwmutex_wrlock l(this->userdata_lock);
for( size_t i = 0; i < IOController::USensorInfo::MaxUserData; i++ ) for( size_t i = 0; i < IOController::USensorInfo::MaxUserData; i++ )
this->userdata[i] = nullptr; this->userdata[i] = nullptr;
}
return *this; return *this;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
#if 0
NCRestorer::SInfo& NCRestorer::SInfo::operator=( const std::shared_ptr<IOController_i::SensorIOInfo>& inf )
{
this->si = inf->si;
this->type = inf->type;
this->priority = inf->priority;
this->default_val = inf->default_val;
this->real_value = inf->real_value;
this->ci = inf->ci;
this->undefined = inf->undefined;
this->blocked = inf->blocked;
this->dbignore = inf->dbignore;
this->any = 0;
return *this;
}
#endif
// ------------------------------------------------------------------------------------------
void NCRestorer::init_depends_signals( IONotifyController* ic ) void NCRestorer::init_depends_signals( IONotifyController* ic )
{ {
for( auto it = ic->ioList.begin(); it != ic->ioList.end(); ++it ) for( auto it = ic->ioList.begin(); it != ic->ioList.end(); ++it )
......
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