mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-29 08:21:12 +02:00
driver/record.cpp, driver/scanepg.cpp, zapit/src/zapit.cpp: try to prevent race
while lock/allocate frontend in case of possible concurrent usage in neutrino and zapit threads
This commit is contained in:
@@ -1621,6 +1621,8 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend *
|
||||
if(live_channel_id != channel_id) {
|
||||
/* first try to get frontend for record with locked live */
|
||||
bool unlock = true;
|
||||
/* executed in neutrino thread - possible race with zap NOWAIT and epg scan zap */
|
||||
CFEManager::getInstance()->Lock();
|
||||
CFEManager::getInstance()->lockFrontend(live_fe);
|
||||
frontend = CFEManager::getInstance()->allocateFE(channel, true);
|
||||
if (frontend == NULL) {
|
||||
@@ -1629,6 +1631,8 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend *
|
||||
CFEManager::getInstance()->unlockFrontend(live_fe);
|
||||
frontend = CFEManager::getInstance()->allocateFE(channel, true);
|
||||
}
|
||||
CFEManager::getInstance()->Unlock();
|
||||
|
||||
if (frontend == NULL)
|
||||
return false;
|
||||
|
||||
|
@@ -129,10 +129,11 @@ void CEpgScan::Next()
|
||||
|
||||
t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
|
||||
|
||||
CFrontend *live_fe = CZapit::getInstance()->GetLiveFrontend();
|
||||
/* executed in neutrino thread - possible race with locks in zapit zap NOWAIT :
|
||||
send zaTo_NOWAIT -> EIT_COMPLETE from sectionsd -> zap and this at the same time
|
||||
send zapTo_NOWAIT -> EIT_COMPLETE from sectionsd -> zap and this at the same time
|
||||
*/
|
||||
CFEManager::getInstance()->Lock();
|
||||
CFrontend *live_fe = CZapit::getInstance()->GetLiveFrontend();
|
||||
CFEManager::getInstance()->lockFrontend(live_fe);
|
||||
#ifdef ENABLE_PIP
|
||||
CFrontend *pip_fe = CZapit::getInstance()->GetPipFrontend();
|
||||
@@ -158,6 +159,7 @@ void CEpgScan::Next()
|
||||
if (pip_fe && pip_fe != live_fe)
|
||||
CFEManager::getInstance()->unlockFrontend(pip_fe);
|
||||
#endif
|
||||
CFEManager::getInstance()->Unlock();
|
||||
if (next_chid)
|
||||
g_Zapit->zapTo_epg(next_chid);
|
||||
}
|
||||
|
@@ -483,6 +483,8 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay
|
||||
INFO("[zapit] zap to %s (%" PRIx64 " tp %" PRIx64 ")", newchannel->getName().c_str(), newchannel->getChannelID(), newchannel->getTransponderId());
|
||||
|
||||
#ifdef ENABLE_PIP
|
||||
/* executed async if zap NOWAIT, race possible with record lock/allocate */
|
||||
CFEManager::getInstance()->Lock();
|
||||
if (pip_fe)
|
||||
CFEManager::getInstance()->lockFrontend(pip_fe);
|
||||
CFrontend * fe = CFEManager::getInstance()->allocateFE(newchannel);
|
||||
@@ -492,6 +494,7 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay
|
||||
StopPip();
|
||||
fe = CFEManager::getInstance()->allocateFE(newchannel);
|
||||
}
|
||||
CFEManager::getInstance()->Unlock();
|
||||
#else
|
||||
CFrontend * fe = CFEManager::getInstance()->allocateFE(newchannel);
|
||||
#endif
|
||||
@@ -681,7 +684,6 @@ bool CZapit::ZapForEpg(const t_channel_id channel_id)
|
||||
{
|
||||
CZapitChannel* newchannel;
|
||||
bool transponder_change;
|
||||
bool ret = false;
|
||||
|
||||
if((newchannel = CServiceManager::getInstance()->FindChannel(channel_id)) == NULL) {
|
||||
INFO("channel_id " PRINTF_CHANNEL_ID_TYPE " not found", channel_id);
|
||||
@@ -689,29 +691,34 @@ bool CZapit::ZapForEpg(const t_channel_id channel_id)
|
||||
}
|
||||
INFO("%s: %s (%" PRIx64 ")", __FUNCTION__, newchannel->getName().c_str(), channel_id);
|
||||
|
||||
/* executed async in zapit thread, race possible with record lock/allocate */
|
||||
CFEManager::getInstance()->Lock();
|
||||
|
||||
CFEManager::getInstance()->lockFrontend(live_fe);
|
||||
#ifdef ENABLE_PIP
|
||||
if (pip_fe && pip_fe != live_fe)
|
||||
CFEManager::getInstance()->lockFrontend(pip_fe);
|
||||
#endif
|
||||
CFrontend * frontend = CFEManager::getInstance()->allocateFE(newchannel);
|
||||
if(frontend == NULL) {
|
||||
ERROR("Cannot get frontend\n");
|
||||
goto __error;
|
||||
}
|
||||
if(!TuneChannel(frontend, newchannel, transponder_change))
|
||||
goto __error;
|
||||
|
||||
if(ParsePatPmt(newchannel))
|
||||
ret = true;
|
||||
|
||||
__error:
|
||||
CFEManager::getInstance()->unlockFrontend(live_fe);
|
||||
#ifdef ENABLE_PIP
|
||||
if (pip_fe && pip_fe != live_fe)
|
||||
CFEManager::getInstance()->unlockFrontend(pip_fe);
|
||||
#endif
|
||||
return ret;
|
||||
CFEManager::getInstance()->Unlock();
|
||||
|
||||
if(frontend == NULL) {
|
||||
ERROR("Cannot get frontend\n");
|
||||
return false;
|
||||
}
|
||||
if(!TuneChannel(frontend, newchannel, transponder_change))
|
||||
return false;
|
||||
|
||||
if(!ParsePatPmt(newchannel))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* set channel/pid volume percent, using current channel_id and pid, if those params is 0 */
|
||||
|
Reference in New Issue
Block a user