[eepg] invalid lock sequence report ... mit vdr-2.4.0

  • Bei der Nutzung von vdr-eepg (git#branch=experimental#commit=584d76601777973253c87580216a7f5b970bae44) friert vdr nach einiger Zeit ein und ist nicht mehr bedienbar.


    Im Log taucht ziemlich rasch nach dem Start bereits ein invalid lock sequence report auf



    Kann das bereits der Grund für das Einfrieren des VDR sein?

    Mein VDR
    vdr4arch mit softhddevice, VDR-2.2.0; KODI 16.1. Mainboard: MSI 785GM-E51, CPU: iAMD Athlon II, GPU: GeForce GTX 550 Ti; nvidia:364.19, DVB1-2: DD Cine S2;  DVB3-4: DD DuoFlex S2;, RAM: 1*2G DDR3, AV-Receiver Pioneer VSX-923K

  • Hallo,

    ich kann das Problem bestätigen. Auch bei mir stürzt der VDR 2.4 regelmäßig ab mit EEPG (friert ein und wird vom watchdog beendet). Ich hab versucht den Fehler zu finden, nur zum einem habe ich keine Ahnung von der VDR Plug-In-API und zweitens ist der Code vom EEPG doch ziemlich zusammengewürfelt und nicht gut zu lesen.

    Wir das Plug-In überhaupt noch aktiv betreut?

  • Ist dein VDR 2.4.0 schon mit allen von Klaus veröffentlichten Patches versehen? ftp://ftp.tvdr.de/vdr/Developer/Patches/vdr-2.4/

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Ein Problem dürfte in der eepg.c in void cFilterEEPG::ProcessPremiere(const u_char *& Data) stecken. Die Funktion holt sich erst einen LOCK_SCHEDULES_WRITE Lock und danach einen LOCK_CHANNELS_READ Lock.


    Mein naiver Lösungsansatz wäre sich die Locks am Anfang der Funktion in der vorgesehenen Reihenfolge zu holen:

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Ich habe jetzt die 4 Patches in meinen VDR eingepflegt, als auch den für EEPG. Leider ohne Erfolg, aber ich denke ich habe das (eines von vielen?) Problem gefunden. EEPG hat eine Funktion "GetChannelByID" in der util.c die ein LOCK_CHANNELS_READ zu Beginn macht. Diese Funktion wird an diversen Stellen aufgerufen, auch von Funktionen die vorher schon andere Locks holen.

    Dummerweise kann man das LOCK_CHANNELS_READ nicht einfach verschieben, da es zusätzlich auch noch Variablen definiert...

    Insgesamt ist das EEPG Plugin meiner Ansicht nach ziemlich zusammengewürfelt. Zu diesem LOCK-Makros steht man braucht nicht unlocken, das passiert automatisch beim verlassen eines scopes, aber wann verlässt man einen scope?

  • Zu diesem LOCK-Makros steht man braucht nicht unlocken, das passiert automatisch beim verlassen eines scopes, aber wann verlässt man einen scope?

    Normalerweise steck alles zwischen zwei zusammengehörenden geschweiften Klammern in einem Scope. Locks kann man über zusätzliche Threads entkoppeln (z.B. indem man mit std::async arbeitet) - leider kann ich das Plugin hier nicht sinnvoll testen, aber probier mal, ob dieser Patch an der kritischen Stelle hilft:

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Dieses Problem scheint damit behoben zu sein, vielen Dank! Doch es kommt das nächste Problem: LOCK_CHANNELS_WRITE in der eit2.c verursacht jetzt die invalid lock sequence...


    Die gleiche Lösung wird hier wohl auch nicht funktionieren: Die Funktion selber ruft "GetChannelByID" auf, wenn ich in Thread A ein write lock hole, dann Thread B starte der auf ein read lock wartet aber Thread A das lock erst freigibt wenn Thread B fertig ist dann habe ich wohl ein dead lock.

    Ich denke die einfachste Lösung ist den Inhalt der Funktion GetChannelByID hier direkt einzufügen, das Lock ist ja schon da.

  • Das wird jetzt nicht mehr gehen, da die Funktion ja einen neuen Thread erzeugt, jetzt muss es ja im urprünglichen Thread, der den Lock hat, ausgeführt werden. Da die Funktion wenn man die ifdefs wegnimmt nur aus 5 Zeilen oder so besteht ist es wohl das einfachste das reinzukopieren in die andere Funktion.

  • Wie lange muss denn der Lock auf die Channels gehalten werden? Darf man sich darauf verlassen, dass er nicht mehr benötigt wird, sobald dasconst cChannel * ChannelObject befüllt wurde?

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Der Lock auf die Channels sollte bei dieser Funktion definitiv außerhalb passieren, denn wenn man den Lock wieder freigibt, ist der cChannel-Pointer auch nur noch bedingt nutzbar. Es sollte also ein neuer Parameter "cChannels* Channels" eingebaut werden und überall entsprechend gefüttert werden.


    Oder man schreibt das Plugin mal grundlegend neu. Gerade, wenn es über Jahre immer wieder um Kleinigkeiten erweitert wurde, muss man manchmal ordentlich aufräumen.


    Lars.

  • Meine ursprüngliche Aussage, das dort wieder die Funktion aufgerufen wird, war falsch, es wird eine Methode einer Klasse mit gleichem Namen aufgerufen. Dennoch ist das Problem nicht einfach lösbar, da hier alles in einer Klasse abläuft und auf die Objekte in der Klasse zugegriffen wird, das kann man nicht einfach in einen neuen Thread packen.

    Angesichts der Code-Qualität in allgemeinen wäre es wohl sinnvoll das mal komplett zu überarbeiten. Ich habe jedoch keine Ahnung von der internen VDR Struktur oder dem Plug-in-API. Auch scheint ein Großteil der Formate für 13° zu sein, ich hab nur 28.2° (Freesat).

  • Ich habe mir das EEPG Plug-In angeschaut und festgestellt das ich Ewigkeiten brauchen werde um da durchzusteigen. Da fiel mir ein das ich vor vielen Jahren mal einen Freesat-Patch hatte, also habe ich danach gesucht in der Hoffnung der ist besser lesbar. Ergebnis: Ja, sehr viel besser.

    Doch noch viel besser, er funktioniert problemlos mit dem VDR 2.4 (er ist für VDR 2.2, ich hab ihn manuell einpflegt):

    http://www.rst38.org.uk/vdr/

    Insgesamt scheint ein Patch für Freesat sehr viel sinnvoller als ein Plug-In, weil effektiv nur wenige Zeilen Code hinzugefügt wird an Stellen an die kein Plug-In hinkommt (die Huffman-Dekodierung ist in eine eigene Datei ausgelagert). Für ein Plug-In muss man sehr viel Code vom VDR duplizieren (was EEPG getan hat).


    Daher empfehle ich statt EEPG einfach den Patch einzuspielen. Natürlich hilft das nur für Freesat, nicht für die anderen Formate die EEPG unterstützt.

  • Danke für den Tipp mit dem Patch. Das funktioniert bei mir auch problemlos.

    Allerdings scheinen mir die zukünftigen Events weniger zu sein, als das mit vdr-eepg der Fall war oder täusche ich mich?


    Mein VDR
    vdr4arch mit softhddevice, VDR-2.2.0; KODI 16.1. Mainboard: MSI 785GM-E51, CPU: iAMD Athlon II, GPU: GeForce GTX 550 Ti; nvidia:364.19, DVB1-2: DD Cine S2;  DVB3-4: DD DuoFlex S2;, RAM: 1*2G DDR3, AV-Receiver Pioneer VSX-923K

  • Ja, das ist mir auch aufgefallen. Ich scheine vor allem Lücken zu haben: Ich habe die aktuelle und nächste Sendung, dann viele Stunden nichts und danach durchgängig.

    Ich habe jetzt zwei Änderungen vorgenommen:


    Ich habe in dem switch-Block in der Funktion cEitFilter:Process für die Freeview-PID einen eigenen Case gemacht:

    Code
    1. case 3842: {
    2. if (Tid >= 0x4E && Tid <= 0x6F)
    3. cEIT EIT(sectionSyncerHash, Source(), Tid, Data);
    4. }
    5. break;

    Damit werden noch auch tables mit den IDs 0x6? verarbeitet. Habe auch den Filter im Konstruktor geändert und die drei Zeilen durch eine ersetzt:

    Set(3842, 0x40, 0xC0);

    Mal schauen ob das einen Unterschied macht, ansonsten vergleiche ich nochmal die Funktion in der die Tabellen ausgewertet werden. Hatte es in der Vergangenheit auch mit EEPG manchmal Lücken im EPG, ich weiß nicht wie dein Empfang ist, aber ich wohne ziemlich an der Ausleuchtgrenze, die Transponder, die eng auf die britischen Inseln fokussiert sind (wie Channel 4 HD), bekomme ich nur bei gutem Wetter, vielleicht kommen daher mal Aussetzer (wobei im Moment der Empfang ziemlich gut ist).

  • Ich habe ein Problem isoliert: Der VDR löscht die Events wieder. Ich habe vor ein paar Stunden durch die Kanäle gezappt, bis das Freesat EPG komplett war, alle Sender die ich in meiner Liste hatte (BBC, Channel 4, E4, Film4, More4, ITV1/2/3/4, Channel 5, 5 Star, 5 USA) hatten bis mindestens Sonntag abend volles EPG.

    Danach zu einem Sender auf 19.2° umgeschaltet und jetzt nach ein paar Stunden: Die Hälfte der Freesat Kanäle hat kein EPG mehr

    Hat da jemand eine Erklärung?