Skip to content
This repository has been archived by the owner on Dec 21, 2020. It is now read-only.

Commit

Permalink
fix deadlock caused by vdr status callback while holding locks
Browse files Browse the repository at this point in the history
  • Loading branch information
FernetMenta committed Mar 10, 2018
1 parent 31c8f71 commit 0c84792
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 54 deletions.
5 changes: 1 addition & 4 deletions vnsiclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ cVNSIClient::cVNSIClient(int fd, unsigned int id, const char *ClientAdr, CVNSITi
{
SetDescription("VNSI Client %u->%s", id, ClientAdr);

m_StatusInterfaceEnabled = false;
Start();
}

Expand Down Expand Up @@ -299,8 +300,6 @@ int cVNSIClient::EpgChange()

void cVNSIClient::Recording(const cDevice *Device, const char *Name, const char *FileName, bool On)
{
cMutexLock lock(&m_msgLock);

if (m_StatusInterfaceEnabled)
{
cResponsePacket resp;
Expand All @@ -324,8 +323,6 @@ void cVNSIClient::Recording(const cDevice *Device, const char *Name, const char

void cVNSIClient::OsdStatusMessage(const char *Message)
{
cMutexLock lock(&m_msgLock);

if (m_StatusInterfaceEnabled && Message)
{
/* Ignore this messages */
Expand Down
98 changes: 48 additions & 50 deletions vnsiclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "cxsocket.h"
#include "channelscancontrol.h"

#include <atomic>
#include <map>
#include <string>

Expand All @@ -53,41 +54,6 @@ class CVNSITimers;
class cVNSIClient : public cThread
, public cStatus
{
const unsigned int m_Id;
cxSocket m_socket;
bool m_loggedIn = false;
bool m_StatusInterfaceEnabled = false;
cLiveStreamer *m_Streamer = nullptr;
bool m_isStreaming = false;
bool m_bSupportRDS = false;
const cString m_ClientAddress;
cRecPlayer *m_RecPlayer = nullptr;
cCharSetConv m_toUTF8;
uint32_t m_protocolVersion;
cMutex m_msgLock;
static cMutex m_timerLock;
cVnsiOsdProvider *m_Osd = nullptr;
CScanControl m_ChannelScanControl;
static bool m_inhibidDataUpdates;
typedef struct
{
int attempts = 0;
time_t lastEvent = 0;
time_t lastTrigger = 0;
} sEpgUpdate;
std::map<int, sEpgUpdate> m_epgUpdate;
CVNSITimers &m_vnsiTimers;

protected:

bool processRequest(cRequestPacket &req);

virtual void Action(void) override;
virtual void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On) override;
virtual void OsdStatusMessage(const char *Message) override;
#if VDRVERSNUM >= 20104
virtual void ChannelChange(const cChannel *Channel) override;
#endif

public:

Expand All @@ -101,27 +67,25 @@ class cVNSIClient : public cThread
void RecordingsChange();
void SignalTimerChange();
int EpgChange();
static bool InhibidDataUpdates() { return m_inhibidDataUpdates; }

unsigned int GetID() { return m_Id; }

static bool InhibidDataUpdates() { return m_inhibidDataUpdates; }

protected:

void Action(void) override;
void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On) override;
void OsdStatusMessage(const char *Message) override;
#if VDRVERSNUM >= 20104
void ChannelChange(const cChannel *Channel) override;
#endif

void SetLoggedIn(bool yesNo) { m_loggedIn = yesNo; }
void SetStatusInterface(bool yesNo) { m_StatusInterfaceEnabled = yesNo; }
bool StartChannelStreaming(cResponsePacket &resp, const cChannel *channel, int32_t priority, uint8_t timeshift, uint32_t timeout);
void StopChannelStreaming();

private:

typedef struct {
bool automatic;
bool radio;
std::string name;
} ChannelGroup;

std::map<std::string, ChannelGroup> m_channelgroups[2];

bool processRequest(cRequestPacket &req);
bool process_Login(cRequestPacket &r);
bool process_GetTime(cRequestPacket &r);
bool process_EnableStatusInterface(cRequestPacket &r);
Expand Down Expand Up @@ -194,9 +158,8 @@ class cVNSIClient : public cThread

cString CreatePiconRef(const cChannel* channel);

private:
/** Static callback functions to interact with wirbelscan plugin over
the plugin service interface */
// Static callback functions to interact with wirbelscan plugin over
// the plugin service interface
friend class CScanControl;

void processSCAN_SetPercentage(int percent);
Expand All @@ -206,4 +169,39 @@ class cVNSIClient : public cThread
void processSCAN_NewChannel(const char *Name, bool isRadio, bool isEncrypted, bool isHD);
void processSCAN_IsFinished();
void processSCAN_SetStatus(int status);

typedef struct
{
bool automatic;
bool radio;
std::string name;
} ChannelGroup;

std::map<std::string, ChannelGroup> m_channelgroups[2];

const unsigned int m_Id;
cxSocket m_socket;
bool m_loggedIn = false;
std::atomic_bool m_StatusInterfaceEnabled;
cLiveStreamer *m_Streamer = nullptr;
bool m_isStreaming = false;
bool m_bSupportRDS = false;
const cString m_ClientAddress;
cRecPlayer *m_RecPlayer = nullptr;
cCharSetConv m_toUTF8;
uint32_t m_protocolVersion;
cMutex m_msgLock;
static cMutex m_timerLock;
cVnsiOsdProvider *m_Osd = nullptr;
CScanControl m_ChannelScanControl;
static bool m_inhibidDataUpdates;

typedef struct
{
int attempts = 0;
time_t lastEvent = 0;
time_t lastTrigger = 0;
} sEpgUpdate;
std::map<int, sEpgUpdate> m_epgUpdate;
CVNSITimers &m_vnsiTimers;
};

0 comments on commit 0c84792

Please sign in to comment.