timerd: prevent events from being deleted while sending them to neutrino

in neutrino's timer list sometimes appears an entry with random values
after deleting one because thread safety is not guaranteed for timerd's
event list while sending items to neutrino, so let's lock the mutex
earlier and unlock it later

Signed-off-by: Christian Schuett <Gaucho316@hotmail.com>
Signed-off-by: Thilo Graf <dbt@novatux.de>


Origin commit data
------------------
Commit: a96fb7b7f0
Author: Gaucho316 <Gaucho316@hotmail.com>
Date: 2014-02-14 (Fri, 14 Feb 2014)
This commit is contained in:
Gaucho316
2014-02-14 18:40:22 +01:00
committed by Jacek Jendrzej
parent 88c27e6c96
commit a21a12ebee
3 changed files with 21 additions and 2 deletions

View File

@@ -59,6 +59,7 @@ bool timerd_parse_command(CBasicMessage::Header &rmsg, int connfd)
case CTimerdMsg::CMD_GETSLEEPTIMER:
rspGetSleeptimer.eventID = 0;
CTimerManager::getInstance()->lockEvents();
if (CTimerManager::getInstance()->listEvents(events))
{
for (pos = events.begin(); pos != events.end(); ++pos)
@@ -71,6 +72,7 @@ bool timerd_parse_command(CBasicMessage::Header &rmsg, int connfd)
}
}
}
CTimerManager::getInstance()->unlockEvents();
CBasicServer::send_data(connfd, &rspGetSleeptimer, sizeof(rspGetSleeptimer));
break;
@@ -78,6 +80,7 @@ bool timerd_parse_command(CBasicMessage::Header &rmsg, int connfd)
CTimerdMsg::commandGetTimer msgGetTimer;
CTimerd::responseGetTimer resp;
CBasicServer::receive_data(connfd,&msgGetTimer, sizeof(msgGetTimer));
CTimerManager::getInstance()->lockEvents();
if(CTimerManager::getInstance()->listEvents(events))
{
if(events[msgGetTimer.eventID])
@@ -134,11 +137,13 @@ bool timerd_parse_command(CBasicMessage::Header &rmsg, int connfd)
}
}
}
CTimerManager::getInstance()->unlockEvents();
CBasicServer::send_data(connfd, &resp, sizeof(CTimerd::responseGetTimer));
break;
case CTimerdMsg::CMD_GETTIMERLIST:
CTimerdMsg::generalInteger responseInteger;
CTimerManager::getInstance()->lockEvents();
responseInteger.number = (CTimerManager::getInstance()->listEvents(events)) ? events.size() : 0;
if (CBasicServer::send_data(connfd, &responseInteger, sizeof(responseInteger)) == true)
@@ -200,6 +205,7 @@ bool timerd_parse_command(CBasicMessage::Header &rmsg, int connfd)
CBasicServer::send_data(connfd, &lresp, sizeof(CTimerd::responseGetTimer));
}
}
CTimerManager::getInstance()->unlockEvents();
break;
case CTimerdMsg::CMD_RESCHEDULETIMER: // event nach vorne oder hinten schieben

View File

@@ -277,12 +277,24 @@ bool CTimerManager::stopEvent(int peventID)
}
//------------------------------------------------------------
int CTimerManager::lockEvents()
{
return pthread_mutex_lock(&tm_eventsMutex);
}
//------------------------------------------------------------
int CTimerManager::unlockEvents()
{
return pthread_mutex_unlock(&tm_eventsMutex);
}
//------------------------------------------------------------
bool CTimerManager::listEvents(CTimerEventMap &Events)
{
if(!&Events)
return false;
pthread_mutex_lock(&tm_eventsMutex);
Events.clear();
for (CTimerEventMap::iterator pos = events.begin(); pos != events.end(); ++pos)
@@ -290,7 +302,6 @@ bool CTimerManager::listEvents(CTimerEventMap &Events)
pos->second->Refresh();
Events[pos->second->eventID] = pos->second;
}
pthread_mutex_unlock(&tm_eventsMutex);
return true;
}
//------------------------------------------------------------

View File

@@ -237,6 +237,8 @@ public:
bool removeEvent(int eventID);
bool stopEvent(int eventID);
CTimerEvent* getNextEvent();
int lockEvents();
int unlockEvents();
bool listEvents(CTimerEventMap &Events);
CTimerd::CTimerEventTypes *getEventType(int eventID);
// int modifyEvent(int eventID, time_t announceTime, time_t alarmTime, time_t stopTime, uint32_t repeatcount, CTimerd::CTimerEventRepeat evrepeat = CTimerd::TIMERREPEAT_ONCE);