mirror of
https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
synced 2023-10-10 19:16:51 +02:00
fixed regression of "live TV must be switched in VDR main thread" change:
deadlock in IGMP streaming server when switching live TV. Previously cComponentIGMP::Accept did all the work including the channel switch with the new cConnectionIGMP waiting for MainThreadHook. But as the new connection is stored *after* Accept, MainThreadHook didn't see it and so wasn't able to switch. The streamdev main thread waited forever. Moved the main work into cComponentIGMP::Welcome.
This commit is contained in:
parent
2fae067cfe
commit
615f101b9d
2
HISTORY
2
HISTORY
@ -1,6 +1,8 @@
|
|||||||
VDR Plugin 'streamdev' Revision History
|
VDR Plugin 'streamdev' Revision History
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
- fixed regression of "live TV must be switched in VDR main thread" change:
|
||||||
|
deadlock in IGMP streaming server when switching live TV.
|
||||||
- streamdev-client returns true in its AvoidRecording() method introduced
|
- streamdev-client returns true in its AvoidRecording() method introduced
|
||||||
with VDR 1.7.19. Note however that the impact of NumProvidedSystems is
|
with VDR 1.7.19. Note however that the impact of NumProvidedSystems is
|
||||||
higher.
|
higher.
|
||||||
|
@ -434,7 +434,7 @@ void cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
|
|||||||
if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) {
|
if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) {
|
||||||
cChannel *channel = Channels.GetByNumber(g - MULTICAST_PRIV_MIN);
|
cChannel *channel = Channels.GetByNumber(g - MULTICAST_PRIV_MIN);
|
||||||
Group->connection = (cConnectionIGMP*) NewClient();
|
Group->connection = (cConnectionIGMP*) NewClient();
|
||||||
if (!Group->connection->Start(channel, Group->group)) {
|
if (!Group->connection->SetChannel(channel, Group->group)) {
|
||||||
DELETENULL(Group->connection);
|
DELETENULL(Group->connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,8 @@ cConnectionIGMP::cConnectionIGMP(const char* Name, int ClientPort, eStreamType S
|
|||||||
cServerConnection(Name, SOCK_DGRAM),
|
cServerConnection(Name, SOCK_DGRAM),
|
||||||
m_LiveStreamer(NULL),
|
m_LiveStreamer(NULL),
|
||||||
m_ClientPort(ClientPort),
|
m_ClientPort(ClientPort),
|
||||||
m_StreamType(StreamType)
|
m_StreamType(StreamType),
|
||||||
|
m_Channel(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,40 +23,46 @@ cConnectionIGMP::~cConnectionIGMP()
|
|||||||
delete m_LiveStreamer;
|
delete m_LiveStreamer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cConnectionIGMP::Start(cChannel *Channel, in_addr_t Dst)
|
bool cConnectionIGMP::SetChannel(cChannel *Channel, in_addr_t Dst)
|
||||||
{
|
{
|
||||||
if (Channel != NULL) {
|
if (Channel) {
|
||||||
cDevice *device = NULL;
|
m_Channel = Channel;
|
||||||
if (ProvidesChannel(Channel, 0))
|
|
||||||
device = GetDevice(Channel, 0);
|
|
||||||
if (device != NULL) {
|
|
||||||
device->SwitchChannel(Channel, false);
|
|
||||||
struct in_addr ip;
|
struct in_addr ip;
|
||||||
ip.s_addr = Dst;
|
ip.s_addr = Dst;
|
||||||
if (Connect(inet_ntoa(ip), m_ClientPort)) {
|
if (Connect(inet_ntoa(ip), m_ClientPort))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
esyslog("streamdev-server IGMP: Connect failed: %m");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog("streamdev-server IGMP: Channel not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cConnectionIGMP::Welcome()
|
||||||
|
{
|
||||||
|
cDevice *device = NULL;
|
||||||
|
if (ProvidesChannel(m_Channel, 0))
|
||||||
|
device = GetDevice(m_Channel, 0);
|
||||||
|
if (device != NULL) {
|
||||||
|
device->SwitchChannel(m_Channel, false);
|
||||||
m_LiveStreamer = new cStreamdevLiveStreamer(0, this);
|
m_LiveStreamer = new cStreamdevLiveStreamer(0, this);
|
||||||
if (m_LiveStreamer->SetChannel(Channel, m_StreamType)) {
|
if (m_LiveStreamer->SetChannel(m_Channel, m_StreamType)) {
|
||||||
m_LiveStreamer->SetDevice(device);
|
m_LiveStreamer->SetDevice(device);
|
||||||
if (!SetDSCP())
|
if (!SetDSCP())
|
||||||
LOG_ERROR_STR("unable to set DSCP sockopt");
|
LOG_ERROR_STR("unable to set DSCP sockopt");
|
||||||
Dprintf("streamer start\n");
|
Dprintf("streamer start\n");
|
||||||
m_LiveStreamer->Start(this);
|
m_LiveStreamer->Start(this);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
esyslog("streamdev-server IGMP: SetDevice failed");
|
esyslog("streamdev-server IGMP: SetChannel failed");
|
||||||
DELETENULL(m_LiveStreamer);
|
DELETENULL(m_LiveStreamer);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
esyslog("streamdev-server IGMP: Connect failed: %m");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
esyslog("streamdev-server IGMP: GetDevice failed");
|
esyslog("streamdev-server IGMP: GetDevice failed");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
esyslog("streamdev-server IGMP: Channel not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cConnectionIGMP::Stop()
|
void cConnectionIGMP::Stop()
|
||||||
{
|
{
|
||||||
|
@ -20,12 +20,14 @@ private:
|
|||||||
cStreamdevLiveStreamer *m_LiveStreamer;
|
cStreamdevLiveStreamer *m_LiveStreamer;
|
||||||
int m_ClientPort;
|
int m_ClientPort;
|
||||||
eStreamType m_StreamType;
|
eStreamType m_StreamType;
|
||||||
|
cChannel *m_Channel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cConnectionIGMP(const char* Name, int ClientPort, eStreamType StreamType);
|
cConnectionIGMP(const char* Name, int ClientPort, eStreamType StreamType);
|
||||||
virtual ~cConnectionIGMP();
|
virtual ~cConnectionIGMP();
|
||||||
|
|
||||||
bool Start(cChannel *Channel, in_addr_t Dst);
|
bool SetChannel(cChannel *Channel, in_addr_t Dst);
|
||||||
|
virtual void Welcome(void);
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
/* Not used here */
|
/* Not used here */
|
||||||
|
Loading…
Reference in New Issue
Block a user