Commit e874d1cb authored by Pavel Vainerman's avatar Pavel Vainerman

(NotifyController): ввёл mutex-ы на списки заказчиков, исправил потенциальную…

(NotifyController): ввёл mutex-ы на списки заказчиков, исправил потенциальную ошибку приводящую к SEGFAULT при работе с заказом пороговых датчиков.. или к "deadlock" (если mutex не так ставить).
parent e73e8f95
......@@ -183,6 +183,10 @@ class IONotifyController:
UniSetTypes::uniset_rwmutex mut;
};
/*! словарь: датчик -> список потребителей */
typedef std::map<UniSetTypes::KeyType,ConsumerListInfo> AskMap;
/*! Информация о пороговом значении */
struct ThresholdInfoExt:
public IONotifyController_i::ThresholdInfo
......@@ -198,7 +202,7 @@ class IONotifyController:
state = IONotifyController_i::NormalThreshold;
}
ConsumerListInfo clst;
ConsumerListInfo clst; /*!< список заказчиков данного порога */
/*! идентификатор дискретного датчика связанного с данным порогом */
UniSetTypes::ObjectId sid;
......@@ -231,11 +235,9 @@ class IONotifyController:
}
};
/*! список порогов (информация по каждому порогу) */
typedef std::list<ThresholdInfoExt> ThresholdExtList;
/*! массив пар датчик->список потребителей */
typedef std::map<UniSetTypes::KeyType,ConsumerListInfo> AskMap;
struct ThresholdsListInfo
{
ThresholdsListInfo(){}
......@@ -243,13 +245,14 @@ class IONotifyController:
UniversalIO::IOType t=UniversalIO::AI ):
si(si),type(t),list(list){}
IOController_i::SensorInfo si;
UniSetTypes::uniset_rwmutex mut;
IOController_i::SensorInfo si; /*!< аналоговый датчик */
IOStateList::iterator ait;
UniversalIO::IOType type;
ThresholdExtList list;
ThresholdExtList list; /*!< список порогов по данному аналоговому датчику */
};
/*! массив пар [датчик,список порогов] */
/*! словарь: аналоговый датчик --> список порогов по нему */
typedef std::map<UniSetTypes::KeyType,ThresholdsListInfo> AskThresholdMap;
protected:
......
......@@ -130,7 +130,7 @@ bool IONotifyController::removeConsumer( ConsumerListInfo& lst, const ConsumerIn
uniset_rwmutex_wrlock l(lst.mut);
for( ConsumerList::iterator li=lst.clst.begin();li!=lst.clst.end(); ++li )
{
if( li->id == cons.id && li->node == cons.node )
if( li->id==cons.id && li->node==cons.node )
{
lst.clst.erase(li);
return true;
......@@ -265,12 +265,15 @@ void IONotifyController::ask(AskMap& askLst, const IOController_i::SensorInfo& s
{
if( askIterator!=askLst.end() ) // существует
{
// ConsumerList lst(askIterator->second);
if( removeConsumer(askIterator->second, cons) )
{
uniset_rwmutex_wrlock l(askIterator->second.mut);
if( askIterator->second.clst.empty() )
askLst.erase(askIterator);
{
// не удаляем, т.к. могут поломаться итераторы
// используемые в это время в других потоках..
// askLst.erase(askIterator);
}
else
{
try
......@@ -375,8 +378,6 @@ void IONotifyController::localSetValue( IOController::IOStateList::iterator& li,
*/
void IONotifyController::send( ConsumerListInfo& lst, UniSetTypes::SensorMessage& sm )
{
return;
TransportMessage tmsg;
uniset_rwmutex_wrlock l(lst.mut);
......@@ -699,9 +700,13 @@ bool IONotifyController::removeThreshold( ThresholdExtList& lst, ThresholdInfoEx
{
if( removeConsumer(it->clst, ci) )
{
uniset_rwmutex_wrlock lock(it->clst.mut);
if( it->clst.clst.empty() )
lst.erase(it);
/* Не удаляем датчик из списка, чтобы не поломать итераторы
которые могут использоваться в этот момент в других потоках*/
// uniset_rwmutex_wrlock lock(it->clst.mut);
// if( it->clst.clst.empty() )
// lst.erase(it);
return true;
}
}
......@@ -714,16 +719,12 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
const IOController_i::SensorInfo& si,
bool send_msg )
{
// {
// uniset_rwmutex_rlock lock(trshMutex);
// поиск списка порогов
UniSetTypes::KeyType skey( key(si.id,si.node) );
AskThresholdMap::iterator lst = askTMap.end();
{
uniset_rwmutex_rlock lock(trshMutex);
lst = askTMap.find(skey);
if( lst == askTMap.end() )
return;
......@@ -758,6 +759,8 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
tm.tv_sec = 0; tm.tv_usec = 0;
gettimeofday(&tm,&tz);
{
uniset_rwmutex_rlock l(lst->second.mut);
for( ThresholdExtList::iterator it=lst->second.list.begin(); it!=lst->second.list.end(); ++it )
{
// Используем здесь sm.value чтобы не делать ещё раз lock на li->second.value
......@@ -816,7 +819,7 @@ void IONotifyController::checkThreshold( IOStateList::iterator& li,
if( send_msg )
send(it->clst, sm);
}
// } // unlock
}
}
// --------------------------------------------------------------------------------------------------------------
IONotifyController::ThresholdExtList::iterator IONotifyController::findThreshold( UniSetTypes::KeyType key, UniSetTypes::ThresholdId tid )
......
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