Bug #2586
openEPG update deadlock with multiple tuners
100%
Description
With multiple tuners present, it appears easy to get EEPG to cause a deadlock caused by actions to update EPG schedules being triggered from both tuners. Tuning into the Sky UK 'EPG Backaround Audio' channel for about 5 minutes is enough to trigger VDR to panic and terminate.
Attached is my proposed fix, which is to simply serialise cFilterEEPG::Process() so that EPG updates.
Tested on VDR 2.4.0 for 5 hours.
Thread 17 (Thread 0x7f64e0ff6700 (LWP 30665)): #0 0x00007f64f568fbe5 in pthread_rwlock_wrlock () from /usr/lib/libpthread.so.0 #1 0x000055a506404697 in cRwLock::Lock(bool, int) () at epg.h:218 #2 0x000055a506406e6f in cStateLock::Lock(cStateKey&, bool, int) () at epg.h:218 #3 0x000055a506389c2a in cSchedules::GetSchedulesWrite (StateKey=..., TimeoutMs=<optimized out>) at epg.c:1238 #4 0x00007f64f422d720 in SI::cEIT2::cEIT2(int, unsigned char, unsigned char const*, util::EFormat, bool) () from /usr/lib/vdr/plugins/libvdr-eepg.so.2.4.0 #5 0x00007f64f4219073 in cFilterEEPG::ProccessContinuous(unsigned short, unsigned char, int, unsigned char const*) () from /usr/lib/vdr/plugins/libvdr-eepg.so.2.4.0 #6 0x00007f64f4220768 in cFilterEEPG::Process(unsigned short, unsigned char, unsigned char const*, int) () from /usr/lib/vdr/plugins/libvdr-eepg.so.2.4.0 #7 0x000055a5063dc5f6 in cSectionHandler::Action (this=0x55a506a4aef0) at sections.c:212 #8 0x000055a506404871 in cThread::StartThread(cThread*) () at epg.h:218 #9 0x00007f64f568aa92 in start_thread () from /usr/lib/libpthread.so.0 #10 0x00007f64f50f7cd3 in clone () from /usr/lib/libc.so.6 Thread 5 (Thread 0x7f64f0a8e700 (LWP 30653)): #0 0x00007f64f568f79e in pthread_rwlock_rdlock () from /usr/lib/libpthread.so.0 #1 0x000055a50640466b in cRwLock::Lock(bool, int) () at epg.h:218 #2 0x000055a506406e6f in cStateLock::Lock(cStateKey&, bool, int) () at epg.h:218 #3 0x000055a506351277 in cChannels::GetChannelsRead (StateKey=..., TimeoutMs=<optimized out>) at channels.c:851 #4 0x00007f64f4229f04 in util::GetChannelByID(tChannelID const&, bool) () from /usr/lib/vdr/plugins/libvdr-eepg.so.2.4.0 #5 0x00007f64f422b826 in util::sortSchedules(cSchedules*, tChannelID) () from /usr/lib/vdr/plugins/libvdr-eepg.so.2.4.0 #6 0x00007f64f421cda2 in cFilterEEPG::LoadIntoSchedule() () from /usr/lib/vdr/plugins/libvdr-eepg.so.2.4.0 #7 0x00007f64f4220dff in cFilterEEPG::Process(unsigned short, unsigned char, unsigned char const*, int) () from /usr/lib/vdr/plugins/libvdr-eepg.so.2.4.0 #8 0x000055a5063dc5f6 in cSectionHandler::Action (this=0x55a5069e9710) at sections.c:212 #9 0x000055a506404871 in cThread::StartThread(cThread*) () at epg.h:218 #10 0x00007f64f568aa92 in start_thread () from /usr/lib/libpthread.so.0 #11 0x00007f64f50f7cd3 in clone () from /usr/lib/libc.so.6
Files
Updated by cheesemonster over 5 years ago
Attached vdr-2.4.0-eepg-lock.patch is a better fix and resolves all the crashing problems. The issue was that LOCK_CHANNELS_WRITE/LOCK_SCHEDULES_WRITE use a timeout of 0 (infinite) so it's quite easy to deadlock the system. Replacing with a timeout of 10ms and handling the lock acquisition failure resolves the problem.
Updated by dimeptr over 5 years ago
Your patch seems OK, I will merge it as soon as I can
Updated by dimeptr over 5 years ago
- Status changed from New to Resolved
- % Done changed from 0 to 100
the patch is added