Commit 9d8d0b0b authored by Pavel Vainerman's avatar Pavel Vainerman

(IONotifyController): сделал защитный mutex на список заказчиков, т.к. при…

(IONotifyController): сделал защитный mutex на список заказчиков, т.к. при большом количестве потоков, происходил SEGFAULT.
parent 7c501bee
...@@ -262,6 +262,55 @@ ...@@ -262,6 +262,55 @@
<item id="6010" name="MBMultiMaster1"/> <item id="6010" name="MBMultiMaster1"/>
<item id="6011" name="RRDServer1"/> <item id="6011" name="RRDServer1"/>
<item id="6012" name="TestProc1"/> <item id="6012" name="TestProc1"/>
<item id="6013" name="TestProc2"/>
<item id="6014" name="TestProc3"/>
<item id="6015" name="TestProc4"/>
<item id="6016" name="TestProc5"/>
<item id="6017" name="TestProc6"/>
<item id="6018" name="TestProc7"/>
<item id="6019" name="TestProc8"/>
<item id="6020" name="TestProc9"/>
<item id="6021" name="TestProc10"/>
<item id="6022" name="TestProc11"/>
<item id="6023" name="TestProc12"/>
<item id="6024" name="TestProc13"/>
<item id="6025" name="TestProc14"/>
<item id="6026" name="TestProc15"/>
<item id="6027" name="TestProc16"/>
<item id="6028" name="TestProc17"/>
<item id="6029" name="TestProc18"/>
<item id="6030" name="TestProc19"/>
<item id="6031" name="TestProc20"/>
<item id="6032" name="TestProc21"/>
<item id="6033" name="TestProc22"/>
<item id="6034" name="TestProc23"/>
<item id="6035" name="TestProc24"/>
<item id="6036" name="TestProc25"/>
<item id="6037" name="TestProc26"/>
<item id="6038" name="TestProc27"/>
<item id="6039" name="TestProc28"/>
<item id="6040" name="TestProc29"/>
<item id="6041" name="TestProc30"/>
<item id="6042" name="TestProc31"/>
<item id="6043" name="TestProc32"/>
<item id="6044" name="TestProc33"/>
<item id="6045" name="TestProc34"/>
<item id="6046" name="TestProc35"/>
<item id="6047" name="TestProc36"/>
<item id="6048" name="TestProc37"/>
<item id="6049" name="TestProc38"/>
<item id="6050" name="TestProc39"/>
<item id="6051" name="TestProc40"/>
<item id="6052" name="TestProc41"/>
<item id="6053" name="TestProc42"/>
<item id="6054" name="TestProc43"/>
<item id="6055" name="TestProc44"/>
<item id="6056" name="TestProc45"/>
<item id="6057" name="TestProc46"/>
<item id="6058" name="TestProc47"/>
<item id="6059" name="TestProc48"/>
<item id="6060" name="TestProc49"/>
<item id="6061" name="TestProc50"/>
</objects> </objects>
</ObjectsMap> </ObjectsMap>
<messages idfromfile="1" name="messages"> <messages idfromfile="1" name="messages">
......
...@@ -33,13 +33,22 @@ int main(int argc, const char **argv) ...@@ -33,13 +33,22 @@ int main(int argc, const char **argv)
if( !shm ) if( !shm )
return 1; return 1;
TestProc tp(conf->getObjectID("TestProc1"));
tp.init_dlog(dlog);
UniSetActivator act; UniSetActivator act;
act.addObject(static_cast<class UniSetObject*>(shm)); act.addObject(static_cast<class UniSetObject*>(shm));
act.addObject(static_cast<class UniSetObject*>(&tp));
int num = conf->getArgPInt("--numproc",20);
for( int i=1; i<=num; i++ )
{
ostringstream s;
s << "TestProc" << i;
cout << "..create " << s.str() << endl;
TestProc* tp = new TestProc(conf->getObjectID(s.str()));
tp->init_dlog(dlog);
act.addObject(static_cast<class UniSetObject*>(tp));
}
SystemMessage sm(SystemMessage::StartUp); SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() ); act.broadcast( sm.transport_msg() );
......
...@@ -139,7 +139,7 @@ class IONotifyController: ...@@ -139,7 +139,7 @@ class IONotifyController:
virtual UniSetTypes::ObjectType getType(){ return UniSetTypes::getObjectType("IONotifyController"); } virtual UniSetTypes::ObjectType getType(){ return UniSetTypes::getObjectType("IONotifyController"); }
virtual void askSensor(const IOController_i::SensorInfo& si, const UniSetTypes::ConsumerInfo& ci, UniversalIO::UIOCommand cmd); virtual void askSensor(const IOController_i::SensorInfo& si, const UniSetTypes::ConsumerInfo& ci, UniversalIO::UIOCommand cmd);
virtual void askThreshold(const IOController_i::SensorInfo& si, const UniSetTypes::ConsumerInfo& ci, virtual void askThreshold(const IOController_i::SensorInfo& si, const UniSetTypes::ConsumerInfo& ci,
UniSetTypes::ThresholdId tid, UniSetTypes::ThresholdId tid,
CORBA::Long lowLimit, CORBA::Long hiLimit, CORBA::Boolean invert, CORBA::Long lowLimit, CORBA::Long hiLimit, CORBA::Boolean invert,
...@@ -176,6 +176,13 @@ class IONotifyController: ...@@ -176,6 +176,13 @@ class IONotifyController:
typedef std::list<ConsumerInfoExt> ConsumerList; typedef std::list<ConsumerInfoExt> ConsumerList;
struct ConsumerListInfo
{
ConsumerListInfo():mut("ConsumerInfoMutex"){}
ConsumerList clst;
UniSetTypes::uniset_rwmutex mut;
};
/*! Информация о пороговом значении */ /*! Информация о пороговом значении */
struct ThresholdInfoExt: struct ThresholdInfoExt:
public IONotifyController_i::ThresholdInfo public IONotifyController_i::ThresholdInfo
...@@ -191,17 +198,17 @@ class IONotifyController: ...@@ -191,17 +198,17 @@ class IONotifyController:
state = IONotifyController_i::NormalThreshold; state = IONotifyController_i::NormalThreshold;
} }
ConsumerList clst; ConsumerListInfo clst;
/*! идентификатор дискретного датчика связанного с данным порогом */ /*! идентификатор дискретного датчика связанного с данным порогом */
UniSetTypes::ObjectId sid; UniSetTypes::ObjectId sid;
/*! итератор в списке датчиков (для оптимально-быстрого доступа) */ /*! итератор в списке датчиков (для оптимально-быстрого доступа) */
IOController::IOStateList::iterator sit; IOController::IOStateList::iterator sit;
/*! инверсная логика */ /*! инверсная логика */
bool invert; bool invert;
inline bool operator== ( const ThresholdInfo& r ) const inline bool operator== ( const ThresholdInfo& r ) const
{ {
return ((id == r.id) && return ((id == r.id) &&
...@@ -223,25 +230,25 @@ class IONotifyController: ...@@ -223,25 +230,25 @@ class IONotifyController:
return r; return r;
} }
}; };
typedef std::list<ThresholdInfoExt> ThresholdExtList; typedef std::list<ThresholdInfoExt> ThresholdExtList;
/*! массив пар датчик->список потребителей */ /*! массив пар датчик->список потребителей */
typedef std::map<UniSetTypes::KeyType,ConsumerList> AskMap; typedef std::map<UniSetTypes::KeyType,ConsumerListInfo> AskMap;
struct ThresholdsListInfo struct ThresholdsListInfo
{ {
ThresholdsListInfo(){} ThresholdsListInfo(){}
ThresholdsListInfo( IOController_i::SensorInfo& si, ThresholdExtList& list, ThresholdsListInfo( IOController_i::SensorInfo& si, ThresholdExtList& list,
UniversalIO::IOType t=UniversalIO::AI ): UniversalIO::IOType t=UniversalIO::AI ):
si(si),type(t),list(list){} si(si),type(t),list(list){}
IOController_i::SensorInfo si; IOController_i::SensorInfo si;
IOStateList::iterator ait; IOStateList::iterator ait;
UniversalIO::IOType type; UniversalIO::IOType type;
ThresholdExtList list; ThresholdExtList list;
}; };
/*! массив пар [датчик,список порогов] */ /*! массив пар [датчик,список порогов] */
typedef std::map<UniSetTypes::KeyType,ThresholdsListInfo> AskThresholdMap; typedef std::map<UniSetTypes::KeyType,ThresholdsListInfo> AskThresholdMap;
...@@ -254,7 +261,7 @@ class IONotifyController: ...@@ -254,7 +261,7 @@ class IONotifyController:
bool myIOFilter(const USensorInfo& ai, CORBA::Long newvalue, UniSetTypes::ObjectId sup_id); bool myIOFilter(const USensorInfo& ai, CORBA::Long newvalue, UniSetTypes::ObjectId sup_id);
//! посылка информации об изменении состояния датчика //! посылка информации об изменении состояния датчика
virtual void send(ConsumerList& lst, UniSetTypes::SensorMessage& sm); virtual void send(ConsumerListInfo& lst, UniSetTypes::SensorMessage& sm);
//! проверка срабатывания пороговых датчиков //! проверка срабатывания пороговых датчиков
virtual void checkThreshold( IOStateList::iterator& li, virtual void checkThreshold( IOStateList::iterator& li,
...@@ -269,7 +276,7 @@ class IONotifyController: ...@@ -269,7 +276,7 @@ class IONotifyController:
/*! сохранение списка заказчиков /*! сохранение списка заказчиков
По умолчанию делает dump, если объявлен dumper. По умолчанию делает dump, если объявлен dumper.
*/ */
virtual void dumpOrdersList(const IOController_i::SensorInfo& si, const IONotifyController::ConsumerList& lst); virtual void dumpOrdersList(const IOController_i::SensorInfo& si, const IONotifyController::ConsumerListInfo& lst);
/*! сохранение списка заказчиков пороговых датчиков /*! сохранение списка заказчиков пороговых датчиков
По умолчанию делает dump, если объявлен dumper. По умолчанию делает dump, если объявлен dumper.
...@@ -290,9 +297,9 @@ class IONotifyController: ...@@ -290,9 +297,9 @@ class IONotifyController:
friend class NCRestorer; friend class NCRestorer;
//---------------------- //----------------------
bool addConsumer(ConsumerList& lst, const UniSetTypes::ConsumerInfo& cons ); //!< добавить потребителя сообщения bool addConsumer(ConsumerListInfo& lst, const UniSetTypes::ConsumerInfo& cons ); //!< добавить потребителя сообщения
bool removeConsumer(ConsumerList& lst, const UniSetTypes::ConsumerInfo& cons ); //!< удалить потребителя сообщения bool removeConsumer(ConsumerListInfo& lst, const UniSetTypes::ConsumerInfo& cons ); //!< удалить потребителя сообщения
//! обработка заказа //! обработка заказа
void ask(AskMap& askLst, const IOController_i::SensorInfo& si, void ask(AskMap& askLst, const IOController_i::SensorInfo& si,
const UniSetTypes::ConsumerInfo& ci, UniversalIO::UIOCommand cmd); const UniSetTypes::ConsumerInfo& ci, UniversalIO::UIOCommand cmd);
...@@ -305,12 +312,12 @@ class IONotifyController: ...@@ -305,12 +312,12 @@ class IONotifyController:
AskMap askIOList; /*!< список потребителей по аналоговым датчикам */ AskMap askIOList; /*!< список потребителей по аналоговым датчикам */
AskThresholdMap askTMap; /*!< список порогов по аналоговым датчикам */ AskThresholdMap askTMap; /*!< список порогов по аналоговым датчикам */
/*! замок для блокирования совместного доступа к cписку потребителей датчиков */ /*! замок для блокирования совместного доступа к cписку потребителей датчиков */
UniSetTypes::uniset_rwmutex askIOMutex; UniSetTypes::uniset_rwmutex askIOMutex;
/*! замок для блокирования совместного доступа к cписку потребителей пороговых датчиков */ /*! замок для блокирования совместного доступа к cписку потребителей пороговых датчиков */
UniSetTypes::uniset_rwmutex trshMutex; UniSetTypes::uniset_rwmutex trshMutex;
int maxAttemtps; /*! timeout for consumer */ int maxAttemtps; /*! timeout for consumer */
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
......
...@@ -68,13 +68,13 @@ class NCRestorer ...@@ -68,13 +68,13 @@ class NCRestorer
}; };
virtual void read( IONotifyController* ic, const std::string& fn="" )=0; virtual void read( IONotifyController* ic, const std::string& fn="" )=0;
virtual void dump(const IONotifyController* ic, SInfo& inf, const IONotifyController::ConsumerList& lst)=0; virtual void dump(const IONotifyController* ic, SInfo& inf, const IONotifyController::ConsumerListInfo& lst)=0;
virtual void dumpThreshold(const IONotifyController* ic, SInfo& inf, const IONotifyController::ThresholdExtList& lst)=0; virtual void dumpThreshold(const IONotifyController* ic, SInfo& inf, const IONotifyController::ThresholdExtList& lst)=0;
protected: protected:
// добавление списка заказчиков // добавление списка заказчиков
static void addlist( IONotifyController* ic, SInfo& inf, IONotifyController::ConsumerList& lst, bool force=false ); static void addlist( IONotifyController* ic, SInfo& inf, IONotifyController::ConsumerListInfo& lst, bool force=false );
// добавление списка порогов и заказчиков // добавление списка порогов и заказчиков
static void addthresholdlist( IONotifyController* ic, SInfo& inf, IONotifyController::ThresholdExtList& lst, bool force=false ); static void addthresholdlist( IONotifyController* ic, SInfo& inf, IONotifyController::ThresholdExtList& lst, bool force=false );
...@@ -151,7 +151,7 @@ class NCRestorer_XML: ...@@ -151,7 +151,7 @@ class NCRestorer_XML:
virtual void read( IONotifyController* ic, const std::string& filename="" ); virtual void read( IONotifyController* ic, const std::string& filename="" );
virtual void read( IONotifyController* ic, const UniXML& xml ); virtual void read( IONotifyController* ic, const UniXML& xml );
virtual void dump(const IONotifyController* ic, SInfo& inf, const IONotifyController::ConsumerList& lst); virtual void dump(const IONotifyController* ic, SInfo& inf, const IONotifyController::ConsumerListInfo& lst);
virtual void dumpThreshold(const IONotifyController* ic, SInfo& inf, const IONotifyController::ThresholdExtList& lst); virtual void dumpThreshold(const IONotifyController* ic, SInfo& inf, const IONotifyController::ThresholdExtList& lst);
protected: protected:
...@@ -164,7 +164,7 @@ class NCRestorer_XML: ...@@ -164,7 +164,7 @@ class NCRestorer_XML:
bool getBaseInfo( const UniXML& xml, xmlNode* it, IOController_i::SensorInfo& si ); bool getBaseInfo( const UniXML& xml, xmlNode* it, IOController_i::SensorInfo& si );
bool getSensorInfo(const UniXML& xml, xmlNode* snode, SInfo& si ); bool getSensorInfo(const UniXML& xml, xmlNode* snode, SInfo& si );
bool getConsumerList(const UniXML& xml,xmlNode* node, IONotifyController::ConsumerList& lst); bool getConsumerList(const UniXML& xml,xmlNode* node, IONotifyController::ConsumerListInfo& lst);
bool getThresholdInfo(const UniXML& xml,xmlNode* tnode, IONotifyController::ThresholdInfoExt& ti); bool getThresholdInfo(const UniXML& xml,xmlNode* tnode, IONotifyController::ThresholdInfoExt& ti);
static void set_dumptime( const UniXML& xml, xmlNode* node ); static void set_dumptime( const UniXML& xml, xmlNode* node );
......
...@@ -256,16 +256,16 @@ void IOController::localSetValue( IOController::IOStateList::iterator& li, ...@@ -256,16 +256,16 @@ void IOController::localSetValue( IOController::IOStateList::iterator& li,
li = ioList.find(key(si.id, si.node)); li = ioList.find(key(si.id, si.node));
if( li==ioList.end() ) if( li==ioList.end() )
{ {
ostringstream err; ostringstream err;
err << myname << "(localSaveValue): Unknown sensor (" << si.id << ":" << si.node << ")" err << myname << "(localSaveValue): Unknown sensor (" << si.id << ":" << si.node << ")"
<< "name: " << conf->oind->getNameById(si.id) << "name: " << conf->oind->getNameById(si.id)
<< "node: " << conf->oind->getMapName(si.node); << "node: " << conf->oind->getMapName(si.node);
throw IOController_i::NameNotFound(err.str().c_str()); throw IOController_i::NameNotFound(err.str().c_str());
} }
bool changed = false; bool changed = false;
{ // lock { // lock
uniset_rwmutex_wrlock lock(li->second.val_lock); uniset_rwmutex_wrlock lock(li->second.val_lock);
......
...@@ -44,7 +44,7 @@ askIOMutex("askIOMutex"), ...@@ -44,7 +44,7 @@ askIOMutex("askIOMutex"),
trshMutex("trshMutex"), trshMutex("trshMutex"),
maxAttemtps(conf->getPIntField("ConsumerMaxAttempts", 5)) maxAttemtps(conf->getPIntField("ConsumerMaxAttempts", 5))
{ {
} }
IONotifyController::IONotifyController(const string& name, const string& section, NCRestorer* d ): IONotifyController::IONotifyController(const string& name, const string& section, NCRestorer* d ):
...@@ -98,12 +98,11 @@ struct FindCons_eq: public unary_function<UniSetTypes::ConsumerInfo, bool> ...@@ -98,12 +98,11 @@ struct FindCons_eq: public unary_function<UniSetTypes::ConsumerInfo, bool>
* \param name - имя вносимого потребителя * \param name - имя вносимого потребителя
* \note Добавление произойдет только если такого потребителя не существует в списке * \note Добавление произойдет только если такого потребителя не существует в списке
*/ */
bool IONotifyController::addConsumer(ConsumerList& lst, const ConsumerInfo& ci ) bool IONotifyController::addConsumer( ConsumerListInfo& lst, const ConsumerInfo& ci )
{ {
// ConsumerList::const_iterator it= find_if(lst.begin(), lst.end(), FindCons_eq(ci)); uniset_rwmutex_wrlock l(lst.mut);
// if(it != lst.end() )
// return; for( ConsumerList::const_iterator it=lst.clst.begin(); it!=lst.clst.end(); ++it )
for( ConsumerList::const_iterator it=lst.begin(); it!=lst.end(); ++it)
{ {
if( it->id==ci.id && it->node==ci.node ) if( it->id==ci.id && it->node==ci.node )
return false; return false;
...@@ -117,8 +116,8 @@ bool IONotifyController::addConsumer(ConsumerList& lst, const ConsumerInfo& ci ) ...@@ -117,8 +116,8 @@ bool IONotifyController::addConsumer(ConsumerList& lst, const ConsumerInfo& ci )
cinf.ref = UniSetObject_i::_narrow(op); cinf.ref = UniSetObject_i::_narrow(op);
} }
catch(...){} catch(...){}
lst.push_front(cinf); lst.clst.push_front(cinf);
return true; return true;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -126,19 +125,18 @@ bool IONotifyController::addConsumer(ConsumerList& lst, const ConsumerInfo& ci ) ...@@ -126,19 +125,18 @@ bool IONotifyController::addConsumer(ConsumerList& lst, const ConsumerInfo& ci )
* \param lst - указатель на список из которго происходит удаление потребителя * \param lst - указатель на список из которго происходит удаление потребителя
* \param name - имя удаляемого потребителя * \param name - имя удаляемого потребителя
*/ */
bool IONotifyController::removeConsumer(ConsumerList& lst, const ConsumerInfo& cons ) bool IONotifyController::removeConsumer( ConsumerListInfo& lst, const ConsumerInfo& cons )
{ {
for( ConsumerList::iterator li=lst.begin();li!=lst.end();++li) uniset_rwmutex_wrlock l(lst.mut);
for( ConsumerList::iterator li=lst.clst.begin();li!=lst.clst.end(); ++li )
{ {
// ConsumerInfo tmp(*li); if( li->id == cons.id && li->node == cons.node )
// if( cons == tmp )
if( li->id == cons.id && li->node == cons.node )
{ {
lst.erase(li); lst.clst.erase(li);
return true; return true;
} }
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -185,7 +183,7 @@ void IONotifyController::askSensor(const IOController_i::SensorInfo& si, ...@@ -185,7 +183,7 @@ void IONotifyController::askSensor(const IOController_i::SensorInfo& si,
smsg.sm_tv_sec = li->second.tv_sec; smsg.sm_tv_sec = li->second.tv_sec;
smsg.sm_tv_usec = li->second.tv_usec; smsg.sm_tv_usec = li->second.tv_usec;
} }
TransportMessage tm(smsg.transport_msg()); TransportMessage tm(smsg.transport_msg());
try try
{ {
...@@ -223,13 +221,13 @@ void IONotifyController::ask(AskMap& askLst, const IOController_i::SensorInfo& s ...@@ -223,13 +221,13 @@ void IONotifyController::ask(AskMap& askLst, const IOController_i::SensorInfo& s
case UniversalIO::UIONotifyChange: case UniversalIO::UIONotifyChange:
case UniversalIO::UIONotifyFirstNotNull: case UniversalIO::UIONotifyFirstNotNull:
{ {
if( askIterator==askLst.end() ) if( askIterator==askLst.end() )
{ {
ConsumerList lst; // создаем новый список ConsumerListInfo lst; // создаем новый список
addConsumer(lst,cons); addConsumer(lst,cons);
// более оптимальный способ(при условии вставки первый раз) // askLst[key]=lst; // более оптимальный способ(при условии вставки первый раз) // askLst[key]=lst;
askLst.insert(AskMap::value_type(k,lst)); askLst.insert(AskMap::value_type(k,lst));
try try
{ {
dumpOrdersList(si,lst); dumpOrdersList(si,lst);
...@@ -270,7 +268,8 @@ void IONotifyController::ask(AskMap& askLst, const IOController_i::SensorInfo& s ...@@ -270,7 +268,8 @@ void IONotifyController::ask(AskMap& askLst, const IOController_i::SensorInfo& s
// ConsumerList lst(askIterator->second); // ConsumerList lst(askIterator->second);
if( removeConsumer(askIterator->second, cons) ) if( removeConsumer(askIterator->second, cons) )
{ {
if( askIterator->second.empty() ) uniset_rwmutex_wrlock l(askIterator->second.mut);
if( askIterator->second.clst.empty() )
askLst.erase(askIterator); askLst.erase(askIterator);
else else
{ {
...@@ -302,7 +301,7 @@ bool IONotifyController::myIOFilter( const USensorInfo& ai, ...@@ -302,7 +301,7 @@ bool IONotifyController::myIOFilter( const USensorInfo& ai,
{ {
if( ai.value == newvalue ) if( ai.value == newvalue )
return false; return false;
return true; return true;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -333,7 +332,7 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li, ...@@ -333,7 +332,7 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
if( prevValue == li->second.value ) if( prevValue == li->second.value )
return; return;
// Рассылаем уведомления только в слуае изменения значения // Рассылаем уведомления только в слуае изменения значения
sm.id = si.id; sm.id = si.id;
sm.node = si.node; sm.node = si.node;
...@@ -348,17 +347,17 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li, ...@@ -348,17 +347,17 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
} // unlock } // unlock
try try
{ {
if( !li->second.dbignore ) if( !li->second.dbignore )
loggingInfo(sm); loggingInfo(sm);
} }
catch(...){} catch(...){}
AskMap::iterator it = askIOList.find( key(si.id,si.node) ); {
if( it!=askIOList.end() )
{ // lock
uniset_rwmutex_rlock lock(askIOMutex); uniset_rwmutex_rlock lock(askIOMutex);
send(it->second, sm); AskMap::iterator it = askIOList.find( key(si.id,si.node) );
if( it!=askIOList.end() )
send(it->second, sm);
} }
// проверка порогов // проверка порогов
...@@ -374,13 +373,16 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li, ...@@ -374,13 +373,16 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
Возможно нужно ввести своего агента на удалённой стороне, который будет заниматься Возможно нужно ввести своего агента на удалённой стороне, который будет заниматься
только приёмом сообщений и локальной рассылкой. Lav только приёмом сообщений и локальной рассылкой. Lav
*/ */
void IONotifyController::send(ConsumerList& lst, UniSetTypes::SensorMessage& sm) void IONotifyController::send( ConsumerListInfo& lst, UniSetTypes::SensorMessage& sm )
{ {
return;
TransportMessage tmsg; TransportMessage tmsg;
uniset_rwmutex_wrlock l(lst.mut);
for( ConsumerList::iterator li=lst.begin();li!=lst.end();++li ) for( ConsumerList::iterator li=lst.clst.begin(); li!=lst.clst.end(); ++li )
{ {
for(int i=0; i<2; i++ ) // на каждый объект по две поптыки for( int i=0; i<2; i++ ) // на каждый объект по две поптыки
{ {
try try
{ {
...@@ -421,10 +423,10 @@ void IONotifyController::send(ConsumerList& lst, UniSetTypes::SensorMessage& sm) ...@@ -421,10 +423,10 @@ void IONotifyController::send(ConsumerList& lst, UniSetTypes::SensorMessage& sm)
<< " catch..." << endl; << " catch..." << endl;
} }
if( maxAttemtps>0 && (--li->attempt <= 0) ) if( maxAttemtps>0 && ( (li->attempt)-- <= 0 ) )
{ {
li = lst.erase(li); li = lst.clst.erase(li);
if( li == lst.end() ) --li; if( li == lst.clst.end() ) --li;
break; break;
} }
...@@ -470,7 +472,7 @@ void IONotifyController::initItem( IOStateList::iterator& li, IOController* ic ) ...@@ -470,7 +472,7 @@ void IONotifyController::initItem( IOStateList::iterator& li, IOController* ic )
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void IONotifyController::dumpOrdersList(const IOController_i::SensorInfo& si, void IONotifyController::dumpOrdersList(const IOController_i::SensorInfo& si,
const IONotifyController::ConsumerList& lst) const IONotifyController::ConsumerListInfo& lst)
{ {
if( restorer == NULL ) if( restorer == NULL )
return; return;
...@@ -526,15 +528,16 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons ...@@ -526,15 +528,16 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
// поиск датчика в списке // поиск датчика в списке
UniSetTypes::KeyType skey( key(si.id,si.node) ); UniSetTypes::KeyType skey( key(si.id,si.node) );
AskThresholdMap::iterator it = askTMap.find(skey); AskThresholdMap::iterator it = askTMap.find(skey);
ThresholdInfoExt ti(tid,lowLimit,hiLimit,invert); ThresholdInfoExt ti(tid,lowLimit,hiLimit,invert);
ti.sit = myioEnd(); ti.sit = myioEnd();
switch( cmd ) switch( cmd )
{ {
case UniversalIO::UIONotify: // заказ case UniversalIO::UIONotify: // заказ
case UniversalIO::UIONotifyChange: case UniversalIO::UIONotifyChange:
{ {
if( it==askTMap.end() ) if( it==askTMap.end() )
{ {
ThresholdExtList lst; // создаем новый список ThresholdExtList lst; // создаем новый список
ThresholdsListInfo tli; ThresholdsListInfo tli;
...@@ -622,7 +625,7 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons ...@@ -622,7 +625,7 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
{ {
uwarn << myname << "(askThreshod): CORBA::SystemException: " uwarn << myname << "(askThreshod): CORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch(...) catch(...)
{ {
uwarn << myname << "(askThreshold): dump catch..." << endl; uwarn << myname << "(askThreshold): dump catch..." << endl;
...@@ -634,7 +637,7 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons ...@@ -634,7 +637,7 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
{ {
if( it!=askTMap.end() ) if( it!=askTMap.end() )
{ {
if( removeThreshold(it->second.list,ti,ci) ) if( removeThreshold(it->second.list,ti,ci) )
{ {
try try
{ {
...@@ -657,8 +660,7 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons ...@@ -657,8 +660,7 @@ void IONotifyController::askThreshold(const IOController_i::SensorInfo& si, cons
break; break;
} }
} // unlock } // unlock
}
}
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
bool IONotifyController::addThreshold(ThresholdExtList& lst, ThresholdInfoExt& ti, const UniSetTypes::ConsumerInfo& ci) bool IONotifyController::addThreshold(ThresholdExtList& lst, ThresholdInfoExt& ti, const UniSetTypes::ConsumerInfo& ci)
{ {
...@@ -697,7 +699,8 @@ bool IONotifyController::removeThreshold( ThresholdExtList& lst, ThresholdInfoEx ...@@ -697,7 +699,8 @@ bool IONotifyController::removeThreshold( ThresholdExtList& lst, ThresholdInfoEx
{ {
if( removeConsumer(it->clst, ci) ) if( removeConsumer(it->clst, ci) )
{ {
if( it->clst.empty() ) uniset_rwmutex_wrlock lock(it->clst.mut);
if( it->clst.clst.empty() )
lst.erase(it); lst.erase(it);
return true; return true;
} }
...@@ -711,36 +714,42 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li, ...@@ -711,36 +714,42 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
const IOController_i::SensorInfo& si, const IOController_i::SensorInfo& si,
bool send_msg ) bool send_msg )
{ {
{ // lock // {
uniset_rwmutex_rlock lock(trshMutex); // uniset_rwmutex_rlock lock(trshMutex);
// поиск списка порогов // поиск списка порогов
UniSetTypes::KeyType skey( key(si.id,si.node) ); UniSetTypes::KeyType skey( key(si.id,si.node) );
AskThresholdMap::iterator lst = askTMap.find(skey); AskThresholdMap::iterator lst = askTMap.end();
if( lst==askTMap.end() )
return;
if( lst->second.list.empty() ) {
return; uniset_rwmutex_rlock lock(trshMutex);
lst = askTMap.find(skey);
if( lst == askTMap.end() )
return;
if( lst->second.list.empty() )
return;
}
if( li == myioEnd() ) if( li == myioEnd() )
li = myiofind(key(si.id, si.node)); li = myiofind(skey);
if( li==myioEnd() ) if( li == myioEnd() )
return; // ??? return; // ???
SensorMessage sm; SensorMessage sm;
sm.id = si.id; sm.id = si.id;
sm.node = si.node; sm.node = si.node;
sm.sensor_type = li->second.type; sm.sensor_type = li->second.type;
sm.priority = (Message::Priority)li->second.priority; sm.priority = (Message::Priority)li->second.priority;
sm.ci = li->second.ci; sm.ci = li->second.ci;
{ {
uniset_rwmutex_rlock lock(li->second.val_lock); uniset_rwmutex_rlock lock(li->second.val_lock);
sm.value = li->second.value; sm.value = li->second.value;
sm.undefined = li->second.undefined; sm.undefined = li->second.undefined;
sm.sm_tv_sec = li->second.tv_sec; sm.sm_tv_sec = li->second.tv_sec;
sm.sm_tv_usec = li->second.tv_usec; sm.sm_tv_usec = li->second.tv_usec;
} }
// текущее время // текущее время
...@@ -749,7 +758,7 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li, ...@@ -749,7 +758,7 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
tm.tv_sec = 0; tm.tv_usec = 0; tm.tv_sec = 0; tm.tv_usec = 0;
gettimeofday(&tm,&tz); gettimeofday(&tm,&tz);
for( ThresholdExtList::iterator it=lst->second.list.begin(); it!=lst->second.list.end(); ++it) for( ThresholdExtList::iterator it=lst->second.list.begin(); it!=lst->second.list.end(); ++it )
{ {
// Используем здесь sm.value чтобы не делать ещё раз lock на li->second.value // Используем здесь sm.value чтобы не делать ещё раз lock на li->second.value
...@@ -771,11 +780,11 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li, ...@@ -771,11 +780,11 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
else if( sm.value <= it->lowlimit ) else if( sm.value <= it->lowlimit )
state = IONotifyController_i::LowThreshold; state = IONotifyController_i::LowThreshold;
} }
// если ничего не менялось.. // если ничего не менялось..
if( it->state == state ) if( it->state == state )
continue; continue;
it->state = state; it->state = state;
sm.tid = it->id; sm.tid = it->id;
...@@ -783,14 +792,14 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li, ...@@ -783,14 +792,14 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
// если состояние не normal, значит порог сработал, // если состояние не normal, значит порог сработал,
// не важно какой.. нижний или верхний (зависит от inverse) // не важно какой.. нижний или верхний (зависит от inverse)
sm.threshold = ( state != IONotifyController_i::NormalThreshold ) ? true : false; sm.threshold = ( state != IONotifyController_i::NormalThreshold ) ? true : false;
// запоминаем время изменения состояния // запоминаем время изменения состояния
it->tv_sec = tm.tv_sec; it->tv_sec = tm.tv_sec;
it->tv_usec = tm.tv_usec; it->tv_usec = tm.tv_usec;
sm.sm_tv_sec = tm.tv_sec; sm.sm_tv_sec = tm.tv_sec;
sm.sm_tv_usec = tm.tv_usec; sm.sm_tv_usec = tm.tv_usec;
// если порог связан с ддатчиком, то надо его выставить // если порог связан с датчиком, то надо его выставить
if( it->sid != UniSetTypes::DefaultObjectId ) if( it->sid != UniSetTypes::DefaultObjectId )
{ {
try try
...@@ -803,14 +812,14 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li, ...@@ -803,14 +812,14 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
} }
} }
// отдельно посылаем сообщения заказчикам порогов, по данному "порогу" // отдельно посылаем сообщения заказчикам по данному "порогу"
if( send_msg ) if( send_msg )
send(it->clst, sm); send(it->clst, sm);
} }
} // unlock // } // unlock
} }
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
IONotifyController::ThresholdExtList::iterator IONotifyController::findThreshold( UniSetTypes::KeyType key, UniSetTypes::ThresholdId tid ) IONotifyController::ThresholdExtList::iterator IONotifyController::findThreshold( UniSetTypes::KeyType key, UniSetTypes::ThresholdId tid )
{ {
{ // lock { // lock
uniset_rwmutex_rlock lock(trshMutex); uniset_rwmutex_rlock lock(trshMutex);
...@@ -827,9 +836,8 @@ IONotifyController::ThresholdExtList::iterator IONotifyController::findThreshold ...@@ -827,9 +836,8 @@ IONotifyController::ThresholdExtList::iterator IONotifyController::findThreshold
} }
} }
} }
ThresholdExtList::iterator it; return ThresholdExtList::iterator();
return it;
} }
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
IONotifyController_i::ThresholdInfo IONotifyController::getThresholdInfo( const IOController_i::SensorInfo& si, IONotifyController_i::ThresholdInfo IONotifyController::getThresholdInfo( const IOController_i::SensorInfo& si,
...@@ -882,8 +890,8 @@ IONotifyController_i::ThresholdList* IONotifyController::getThresholds( const IO ...@@ -882,8 +890,8 @@ IONotifyController_i::ThresholdList* IONotifyController::getThresholds( const IO
try try
{ {
res->si = it->second.si; res->si = it->second.si;
res->value = IOController::localGetValue(it->second.ait,it->second.si); res->value = IOController::localGetValue(it->second.ait,it->second.si);
res->type = it->second.type; res->type = it->second.type;
} }
catch( Exception& ex ) catch( Exception& ex )
{ {
...@@ -897,12 +905,12 @@ IONotifyController_i::ThresholdList* IONotifyController::getThresholds( const IO ...@@ -897,12 +905,12 @@ IONotifyController_i::ThresholdList* IONotifyController::getThresholds( const IO
unsigned int k=0; unsigned int k=0;
for( ThresholdExtList::const_iterator it2= it->second.list.begin(); it2!=it->second.list.end(); ++it2 ) for( ThresholdExtList::const_iterator it2= it->second.list.begin(); it2!=it->second.list.end(); ++it2 )
{ {
res->tlist[k].id = it2->id; res->tlist[k].id = it2->id;
res->tlist[k].hilimit = it2->hilimit; res->tlist[k].hilimit = it2->hilimit;
res->tlist[k].lowlimit = it2->lowlimit; res->tlist[k].lowlimit = it2->lowlimit;
res->tlist[k].state = it2->state; res->tlist[k].state = it2->state;
res->tlist[k].tv_sec = it2->tv_sec; res->tlist[k].tv_sec = it2->tv_sec;
res->tlist[k].tv_usec = it2->tv_usec; res->tlist[k].tv_usec = it2->tv_usec;
k++; k++;
} }
...@@ -915,6 +923,7 @@ IONotifyController_i::ThresholdsListSeq* IONotifyController::getThresholdsList() ...@@ -915,6 +923,7 @@ IONotifyController_i::ThresholdsListSeq* IONotifyController::getThresholdsList()
res->length( askTMap.size() ); res->length( askTMap.size() );
uniset_rwmutex_rlock lock(trshMutex);
if( !askTMap.empty() ) if( !askTMap.empty() )
{ {
unsigned int i=0; unsigned int i=0;
...@@ -976,18 +985,18 @@ void IONotifyController::onChangeUndefinedState( IOStateList::iterator& lit, IOC ...@@ -976,18 +985,18 @@ void IONotifyController::onChangeUndefinedState( IOStateList::iterator& lit, IOC
} // unlock } // unlock
try try
{ {
if( !it.dbignore ) if( !it.dbignore )
loggingInfo(sm); loggingInfo(sm);
} }
catch(...){} catch(...){}
AskMap::iterator it1 = askIOList.find( key(it.si.id,it.si.node) ); { // lock
if( it1!=askIOList.end() ) uniset_rwmutex_rlock lock(askIOMutex);
{ // lock AskMap::iterator it1 = askIOList.find( key(it.si.id,it.si.node) );
uniset_rwmutex_rlock lock(askIOMutex); if( it1!=askIOList.end() )
send(it1->second, sm); send(it1->second, sm);
} // unlock } // unlock
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -996,7 +1005,7 @@ IDSeq* IONotifyController::askSensorsSeq( const UniSetTypes::IDSeq& lst, ...@@ -996,7 +1005,7 @@ IDSeq* IONotifyController::askSensorsSeq( const UniSetTypes::IDSeq& lst,
UniversalIO::UIOCommand cmd) UniversalIO::UIOCommand cmd)
{ {
UniSetTypes::IDList badlist; // cписок не найденных идентификаторов UniSetTypes::IDList badlist; // cписок не найденных идентификаторов
IOController_i::SensorInfo si; IOController_i::SensorInfo si;
int size = lst.length(); int size = lst.length();
......
...@@ -40,7 +40,7 @@ NCRestorer::~NCRestorer() ...@@ -40,7 +40,7 @@ NCRestorer::~NCRestorer()
{ {
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void NCRestorer::addlist( IONotifyController* ic, SInfo& inf, IONotifyController::ConsumerList& lst, bool force ) void NCRestorer::addlist( IONotifyController* ic, SInfo& inf, IONotifyController::ConsumerListInfo& lst, bool force )
{ {
UniSetTypes::KeyType k( key(inf.si.id,inf.si.node) ); UniSetTypes::KeyType k( key(inf.si.id,inf.si.node) );
......
...@@ -97,7 +97,7 @@ void NCRestorer_XML::init( const std::string& fname ) ...@@ -97,7 +97,7 @@ void NCRestorer_XML::init( const std::string& fname )
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
void NCRestorer_XML::dump(const IONotifyController* ic, SInfo& inf, void NCRestorer_XML::dump(const IONotifyController* ic, SInfo& inf,
const IONotifyController::ConsumerList& lst) const IONotifyController::ConsumerListInfo& lst)
{ {
uwarn << "NCRestorer_XML::dump NOT SUPPORT!!!!" << endl; uwarn << "NCRestorer_XML::dump NOT SUPPORT!!!!" << endl;
} }
...@@ -409,7 +409,7 @@ void NCRestorer_XML::read_consumers( const UniXML& xml, xmlNode* it, ...@@ -409,7 +409,7 @@ void NCRestorer_XML::read_consumers( const UniXML& xml, xmlNode* it,
UniXML_iterator cit(cnode); UniXML_iterator cit(cnode);
if( cit.goChildren() ) if( cit.goChildren() )
{ {
IONotifyController::ConsumerList lst; IONotifyController::ConsumerListInfo lst;
if( getConsumerList(xml,cit,lst) ) if( getConsumerList(xml,cit,lst) )
addlist(ic,inf,lst,true); addlist(ic,inf,lst,true);
} }
...@@ -417,8 +417,8 @@ void NCRestorer_XML::read_consumers( const UniXML& xml, xmlNode* it, ...@@ -417,8 +417,8 @@ void NCRestorer_XML::read_consumers( const UniXML& xml, xmlNode* it,
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
bool NCRestorer_XML::getConsumerList( const UniXML& xml,xmlNode* node, bool NCRestorer_XML::getConsumerList( const UniXML& xml, xmlNode* node,
IONotifyController::ConsumerList& lst ) IONotifyController::ConsumerListInfo& lst )
{ {
UniXML_iterator it(node); UniXML_iterator it(node);
for(;it;it.goNext()) for(;it;it.goNext())
...@@ -431,7 +431,7 @@ bool NCRestorer_XML::getConsumerList( const UniXML& xml,xmlNode* node, ...@@ -431,7 +431,7 @@ bool NCRestorer_XML::getConsumerList( const UniXML& xml,xmlNode* node,
continue; continue;
IONotifyController::ConsumerInfoExt cinf(ci); IONotifyController::ConsumerInfoExt cinf(ci);
lst.push_back(cinf); lst.clst.push_back(cinf);
cslot(xml,it,node); cslot(xml,it,node);
} }
......
...@@ -179,6 +179,7 @@ const uniset_rwmutex &uniset_rwmutex::operator=( const uniset_rwmutex& r ) ...@@ -179,6 +179,7 @@ const uniset_rwmutex &uniset_rwmutex::operator=( const uniset_rwmutex& r )
s << r.nm << "." << (++num); s << r.nm << "." << (++num);
nm = s.str(); nm = s.str();
unlock(); unlock();
MUTEX_DEBUG(cerr << "...copy mutex..." << nm << endl;)
} }
return *this; return *this;
......
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