Posts by stefan.r

    Quote

    SetChannel() is given a cChannel and is supposed to set that channel. It has no business handling timers!
    If a plugin wants to do something with timers as a reaction to SetChannel, it shall do so in a separate thread.

    Hm, ok, you definitely got a point there ;-). Seems like the plugin authors intention behind this is similar to the case described here. If I can find the time, I will have a lock at the solution you described there.


    Quote

    Should the member cChannel ever be deleted while the cDisplayChannel still lives, it will remain valid in the list's garbage collector, until the cDisplayChannel is closed. So calling SetChannel with that member is OK.

    Understood. Thanks for the clarification.

    Hi,


    i have looked into this problem. As Jinx already described, the locking sequence in this case is first channels and then timers. However, it is not the skindesigner plugin that locks the channels, but the vdr core.
    The channels are locked in cDisplayChannel::cDisplayChannel(int, bool) which afterwards calls cDisplayChannel::DisplayChannel(void) which in turn calls the SetChannel(cChannel, int) method of the current skin.
    Within that call, the skindesigner plugin then locks the timers.


    I don`t see how that could be fixed in the plugin. If the vdr core requests a lock and does a virtual call into a plugin in the scope of that lock, the plugin is only allowed to request locks further down in the sequence.
    My suggestion would be to ensure that in situations like this, the core not only requests a specific lock but all previous locks in the sequence as well (e.g. when the core wants to lock the channels, it should lock the timers as well, if there is a virtual function call in the current scope).


    For this particular sequence violation, one might also argue that the lock on the channels is not correct in the first place, since the lifetime of the cChannel* it should guard is longer than the lifetime of the lock (e.g. the lock is in the scope of the constructor while the pointer is a class member). So currently there is actually no guarantee that the channel pointer remains valid with or without the lock. Or did I get something wrong here?


    Regards,
    Stefan

    stefan.r
    Vielen Dank für den Patch! Damit habe ich wieder Bild bei n-tv HD


    Warum sind denn eigentlich die CAIDs (aus der Channels.conf)

    Code
    1830,1843,1860,98C,9C4,648,650,186A,500


    zu groß für den 512 Byte Puffer?
    Selbst wenn ich die 9x4 (z. B. 1843) rechne sind das "nur" 36 Byte (Zeichen)

    In so einem Descriptor steht schon noch mehr drin als nur die CAID. Erst mal kommen 6 Byte Header (davon sind Byte 3+4 die CAID) und danach bis zu 256 Byte Nutzdaten. Und die Methode GetCaDescriptors gibt ja eine Liste zurück. In den Buffer passt im Worst Case also nur einer.

    Hallo zusammen,


    jetzt muss ich mich doch mal zu Wort melden. Lese hier normalerweise nur mit ;)...
    Ich hab mal etwas gedebugged:
    die "Length" die da "AddCaDescriptors" übergeben wird kommt in dem Fall immer von


    int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)


    aus "pat.h". Laut Kommentar gibt die Funktion nur dann -1 zurück, wenn der Buffer "Data" zu klein ist, um alle CA Descriptors zu speichern. Die cCiCaPmt Konstrukturen übergeben hier immer einen 512B großen Buffer. Hab die testweise mal auf 1K vergrößert und jetzt scheints wieder zu laufen.


    Den entsprechenden Patch findet Ihr im Anhang. Allerdings verstehe ich von der Materie zu wenig, um zu beurteilen, ob das wirklich eine gute Lösung ist. Die 512B scheinen mir genauso willkürlich wie 1K. Oder gibt`s da irgendeinen Standard, laut dem 512B normalerweise die Obergrenze sind.


    Gruß,
    Stefan