mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-29 16:31:11 +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) {
|
if(live_channel_id != channel_id) {
|
||||||
/* first try to get frontend for record with locked live */
|
/* first try to get frontend for record with locked live */
|
||||||
bool unlock = true;
|
bool unlock = true;
|
||||||
|
/* executed in neutrino thread - possible race with zap NOWAIT and epg scan zap */
|
||||||
|
CFEManager::getInstance()->Lock();
|
||||||
CFEManager::getInstance()->lockFrontend(live_fe);
|
CFEManager::getInstance()->lockFrontend(live_fe);
|
||||||
frontend = CFEManager::getInstance()->allocateFE(channel, true);
|
frontend = CFEManager::getInstance()->allocateFE(channel, true);
|
||||||
if (frontend == NULL) {
|
if (frontend == NULL) {
|
||||||
@@ -1629,6 +1631,8 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend *
|
|||||||
CFEManager::getInstance()->unlockFrontend(live_fe);
|
CFEManager::getInstance()->unlockFrontend(live_fe);
|
||||||
frontend = CFEManager::getInstance()->allocateFE(channel, true);
|
frontend = CFEManager::getInstance()->allocateFE(channel, true);
|
||||||
}
|
}
|
||||||
|
CFEManager::getInstance()->Unlock();
|
||||||
|
|
||||||
if (frontend == NULL)
|
if (frontend == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@@ -129,10 +129,11 @@ void CEpgScan::Next()
|
|||||||
|
|
||||||
t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID();
|
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 :
|
/* 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);
|
CFEManager::getInstance()->lockFrontend(live_fe);
|
||||||
#ifdef ENABLE_PIP
|
#ifdef ENABLE_PIP
|
||||||
CFrontend *pip_fe = CZapit::getInstance()->GetPipFrontend();
|
CFrontend *pip_fe = CZapit::getInstance()->GetPipFrontend();
|
||||||
@@ -158,6 +159,7 @@ void CEpgScan::Next()
|
|||||||
if (pip_fe && pip_fe != live_fe)
|
if (pip_fe && pip_fe != live_fe)
|
||||||
CFEManager::getInstance()->unlockFrontend(pip_fe);
|
CFEManager::getInstance()->unlockFrontend(pip_fe);
|
||||||
#endif
|
#endif
|
||||||
|
CFEManager::getInstance()->Unlock();
|
||||||
if (next_chid)
|
if (next_chid)
|
||||||
g_Zapit->zapTo_epg(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());
|
INFO("[zapit] zap to %s (%" PRIx64 " tp %" PRIx64 ")", newchannel->getName().c_str(), newchannel->getChannelID(), newchannel->getTransponderId());
|
||||||
|
|
||||||
#ifdef ENABLE_PIP
|
#ifdef ENABLE_PIP
|
||||||
|
/* executed async if zap NOWAIT, race possible with record lock/allocate */
|
||||||
|
CFEManager::getInstance()->Lock();
|
||||||
if (pip_fe)
|
if (pip_fe)
|
||||||
CFEManager::getInstance()->lockFrontend(pip_fe);
|
CFEManager::getInstance()->lockFrontend(pip_fe);
|
||||||
CFrontend * fe = CFEManager::getInstance()->allocateFE(newchannel);
|
CFrontend * fe = CFEManager::getInstance()->allocateFE(newchannel);
|
||||||
@@ -492,6 +494,7 @@ bool CZapit::ZapIt(const t_channel_id channel_id, bool forupdate, bool startplay
|
|||||||
StopPip();
|
StopPip();
|
||||||
fe = CFEManager::getInstance()->allocateFE(newchannel);
|
fe = CFEManager::getInstance()->allocateFE(newchannel);
|
||||||
}
|
}
|
||||||
|
CFEManager::getInstance()->Unlock();
|
||||||
#else
|
#else
|
||||||
CFrontend * fe = CFEManager::getInstance()->allocateFE(newchannel);
|
CFrontend * fe = CFEManager::getInstance()->allocateFE(newchannel);
|
||||||
#endif
|
#endif
|
||||||
@@ -681,7 +684,6 @@ bool CZapit::ZapForEpg(const t_channel_id channel_id)
|
|||||||
{
|
{
|
||||||
CZapitChannel* newchannel;
|
CZapitChannel* newchannel;
|
||||||
bool transponder_change;
|
bool transponder_change;
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
if((newchannel = CServiceManager::getInstance()->FindChannel(channel_id)) == NULL) {
|
if((newchannel = CServiceManager::getInstance()->FindChannel(channel_id)) == NULL) {
|
||||||
INFO("channel_id " PRINTF_CHANNEL_ID_TYPE " not found", channel_id);
|
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);
|
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);
|
CFEManager::getInstance()->lockFrontend(live_fe);
|
||||||
#ifdef ENABLE_PIP
|
#ifdef ENABLE_PIP
|
||||||
if (pip_fe && pip_fe != live_fe)
|
if (pip_fe && pip_fe != live_fe)
|
||||||
CFEManager::getInstance()->lockFrontend(pip_fe);
|
CFEManager::getInstance()->lockFrontend(pip_fe);
|
||||||
#endif
|
#endif
|
||||||
CFrontend * frontend = CFEManager::getInstance()->allocateFE(newchannel);
|
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);
|
CFEManager::getInstance()->unlockFrontend(live_fe);
|
||||||
#ifdef ENABLE_PIP
|
#ifdef ENABLE_PIP
|
||||||
if (pip_fe && pip_fe != live_fe)
|
if (pip_fe && pip_fe != live_fe)
|
||||||
CFEManager::getInstance()->unlockFrontend(pip_fe);
|
CFEManager::getInstance()->unlockFrontend(pip_fe);
|
||||||
#endif
|
#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 */
|
/* set channel/pid volume percent, using current channel_id and pid, if those params is 0 */
|
||||||
|
Reference in New Issue
Block a user