Improved locking for CAM slots and made the pure functions of cCiAdapter have default implementations

This commit is contained in:
Klaus Schmidinger 2014-01-14 12:21:17 +01:00
parent dbf342df3c
commit e7c86c6760
4 changed files with 16 additions and 11 deletions

View File

@ -8132,8 +8132,11 @@ Video Disk Recorder Revision History
and also to use the correct directory with --edit (the latter reported by Marko and also to use the correct directory with --edit (the latter reported by Marko
Mäkelä). Mäkelä).
2014-01-07: Version 2.1.4 2014-01-14: Version 2.1.4
- Updated 'sources.conf' (thanks to Antti Hartikainen). - Updated 'sources.conf' (thanks to Antti Hartikainen).
- cFont::CreateFont() now returns a dummy font in case there are no fonts installed. - cFont::CreateFont() now returns a dummy font in case there are no fonts installed.
This prevents a crash with the LCARS skin on a system that has no fonts. This prevents a crash with the LCARS skin on a system that has no fonts.
- Improved locking for CAM slots and made the pure functions of cCiAdapter have
default implementations, to fix a possible crash with CI adapters and CAM slots
that are implemented in a plugin.

4
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.c 3.4 2014/01/02 10:31:12 kls Exp $ * $Id: ci.c 3.5 2014/01/14 12:03:37 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -1584,6 +1584,8 @@ cCamSlot::cCamSlot(cCiAdapter *CiAdapter, bool ReceiveCaPids)
cCamSlot::~cCamSlot() cCamSlot::~cCamSlot()
{ {
if (ciAdapter && ciAdapter->assignedDevice)
ciAdapter->assignedDevice->SetCamSlot(NULL);
delete caPidReceiver; delete caPidReceiver;
CamSlots.Del(this, false); CamSlots.Del(this, false);
DeleteAllConnections(); DeleteAllConnections();

12
ci.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.h 3.3 2014/01/02 10:14:39 kls Exp $ * $Id: ci.h 3.4 2014/01/14 11:53:52 kls Exp $
*/ */
#ifndef __CI_H #ifndef __CI_H
@ -88,19 +88,19 @@ protected:
///< Handles the attached CAM slots in a separate thread. ///< Handles the attached CAM slots in a separate thread.
///< The derived class must call the Start() function to ///< The derived class must call the Start() function to
///< actually start CAM handling. ///< actually start CAM handling.
virtual int Read(uint8_t *Buffer, int MaxLength) = 0; virtual int Read(uint8_t *Buffer, int MaxLength) { return 0; }
///< Reads one chunk of data into the given Buffer, up to MaxLength bytes. ///< Reads one chunk of data into the given Buffer, up to MaxLength bytes.
///< If no data is available immediately, wait for up to CAM_READ_TIMEOUT. ///< If no data is available immediately, wait for up to CAM_READ_TIMEOUT.
///< Returns the number of bytes read (in case of an error it will also ///< Returns the number of bytes read (in case of an error it will also
///< return 0). ///< return 0).
virtual void Write(const uint8_t *Buffer, int Length) = 0; virtual void Write(const uint8_t *Buffer, int Length) {}
///< Writes Length bytes of the given Buffer. ///< Writes Length bytes of the given Buffer.
virtual bool Reset(int Slot) = 0; virtual bool Reset(int Slot) { return false; }
///< Resets the CAM in the given Slot. ///< Resets the CAM in the given Slot.
///< Returns true if the operation was successful. ///< Returns true if the operation was successful.
virtual eModuleStatus ModuleStatus(int Slot) = 0; virtual eModuleStatus ModuleStatus(int Slot) { return msNone; }
///< Returns the status of the CAM in the given Slot. ///< Returns the status of the CAM in the given Slot.
virtual bool Assign(cDevice *Device, bool Query = false) = 0; virtual bool Assign(cDevice *Device, bool Query = false) { return false; }
///< Assigns this adapter to the given Device, if this is possible. ///< Assigns this adapter to the given Device, if this is possible.
///< If Query is 'true', the adapter only checks whether it can be ///< If Query is 'true', the adapter only checks whether it can be
///< assigned to the Device, but doesn't actually assign itself to it. ///< assigned to the Device, but doesn't actually assign itself to it.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.c 3.7 2014/01/02 10:31:58 kls Exp $ * $Id: device.c 3.8 2014/01/14 11:58:49 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -358,6 +358,7 @@ bool cDevice::HasCi(void)
void cDevice::SetCamSlot(cCamSlot *CamSlot) void cDevice::SetCamSlot(cCamSlot *CamSlot)
{ {
LOCK_THREAD;
camSlot = CamSlot; camSlot = CamSlot;
} }
@ -1575,6 +1576,7 @@ void cDevice::Action(void)
while (Running()) { while (Running()) {
// Read data from the DVR device: // Read data from the DVR device:
uchar *b = NULL; uchar *b = NULL;
LOCK_THREAD;
if (GetTSPacket(b)) { if (GetTSPacket(b)) {
if (b) { if (b) {
int Pid = TsPid(b); int Pid = TsPid(b);
@ -1599,7 +1601,6 @@ void cDevice::Action(void)
} }
} }
// Distribute the packet to all attached receivers: // Distribute the packet to all attached receivers:
Lock();
for (int i = 0; i < MAXRECEIVERS; i++) { for (int i = 0; i < MAXRECEIVERS; i++) {
if (receiver[i] && receiver[i]->WantsPid(Pid)) { if (receiver[i] && receiver[i]->WantsPid(Pid)) {
if (DetachReceivers) { if (DetachReceivers) {
@ -1612,7 +1613,6 @@ void cDevice::Action(void)
ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber); ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber);
} }
} }
Unlock();
} }
} }
else else