Don't keep a pointer to the connection in components MulticastGroup

structure as the connection may now be deleted from outside via menu.
This commit is contained in:
Frank Schmirler 2011-11-25 00:24:37 +01:00
parent 7347e24123
commit 9b91301d94
4 changed files with 29 additions and 19 deletions

View File

@ -6,6 +6,7 @@
#include "server/componentIGMP.h" #include "server/componentIGMP.h"
#include "server/connectionIGMP.h" #include "server/connectionIGMP.h"
#include "server/server.h"
#include "server/setup.h" #include "server/setup.h"
#ifndef IGMP_ALL_HOSTS #ifndef IGMP_ALL_HOSTS
@ -37,7 +38,6 @@
class cMulticastGroup: public cListObject class cMulticastGroup: public cListObject
{ {
public: public:
cConnectionIGMP *connection;
in_addr_t group; in_addr_t group;
in_addr_t reporter; in_addr_t reporter;
struct timeval timeout; struct timeval timeout;
@ -48,7 +48,6 @@ public:
}; };
cMulticastGroup::cMulticastGroup(in_addr_t Group) : cMulticastGroup::cMulticastGroup(in_addr_t Group) :
connection(NULL),
group(Group), group(Group),
reporter(0) reporter(0)
{ {
@ -235,10 +234,7 @@ cServerConnection* cComponentIGMP::ProcessMessage(struct igmp *Igmp, in_addr_t G
group = new cMulticastGroup(Group); group = new cMulticastGroup(Group);
m_Groups.Add(group); m_Groups.Add(group);
} }
if (!group->connection) { conn = IGMPStartMulticast(group);
IGMPStartMulticast(group);
conn = group->connection;
}
IGMPStartTimer(group, Sender); IGMPStartTimer(group, Sender);
if (Igmp->igmp_type == IGMP_V1_MEMBERSHIP_REPORT) if (Igmp->igmp_type == IGMP_V1_MEMBERSHIP_REPORT)
IGMPStartV1HostTimer(group); IGMPStartV1HostTimer(group);
@ -430,20 +426,36 @@ void cComponentIGMP::IGMPSendGroupQuery(cMulticastGroup* Group)
IGMPSendQuery(Group->group, IGMP_LAST_MEMBER_QUERY_INTERVAL_TS); IGMPSendQuery(Group->group, IGMP_LAST_MEMBER_QUERY_INTERVAL_TS);
} }
void cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group) cServerConnection* cComponentIGMP::IGMPStartMulticast(cMulticastGroup* Group)
{ {
cServerConnection *conn = NULL;
in_addr_t g = ntohl(Group->group); in_addr_t g = ntohl(Group->group);
if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) { if (g > MULTICAST_PRIV_MIN && g <= MULTICAST_PRIV_MAX) {
cThreadLock lock;
cChannel *channel = Channels.GetByNumber(g - MULTICAST_PRIV_MIN); cChannel *channel = Channels.GetByNumber(g - MULTICAST_PRIV_MIN);
Group->connection = (cConnectionIGMP*) NewClient(); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
if (!Group->connection->SetChannel(channel, Group->group)) { cServerConnection *s = clients.First();
DELETENULL(Group->connection); while (s) {
if (s->RemoteIpAddr() == Group->group)
break;
s = clients.Next(s);
}
if (!s) {
conn = NewClient();
if (!((cConnectionIGMP *)conn)->SetChannel(channel, Group->group)) {
DELETENULL(conn);
}
} }
} }
return conn;
} }
void cComponentIGMP::IGMPStopMulticast(cMulticastGroup* Group) void cComponentIGMP::IGMPStopMulticast(cMulticastGroup* Group)
{ {
if (Group->connection) cThreadLock lock;
Group->connection->Stop(); const cList<cServerConnection>& clients = cStreamdevServer::Clients(lock);
for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) {
if (s->RemoteIpAddr() == Group->group)
s->Close();
}
} }

View File

@ -10,7 +10,6 @@
#include <vdr/thread.h> #include <vdr/thread.h>
#include "server/component.h" #include "server/component.h"
class cConnectionIGMP;
class cMulticastGroup; class cMulticastGroup;
class cComponentIGMP: public cServerComponent, public cThread { class cComponentIGMP: public cServerComponent, public cThread {
@ -42,7 +41,7 @@ private:
void IGMPStartRetransmitTimer(cMulticastGroup* Group); void IGMPStartRetransmitTimer(cMulticastGroup* Group);
void IGMPClearRetransmitTimer(cMulticastGroup* Group); void IGMPClearRetransmitTimer(cMulticastGroup* Group);
void IGMPSendGroupQuery(cMulticastGroup* Group); void IGMPSendGroupQuery(cMulticastGroup* Group);
void IGMPStartMulticast(cMulticastGroup* Group); cServerConnection* IGMPStartMulticast(cMulticastGroup* Group);
void IGMPStopMulticast(cMulticastGroup* Group); void IGMPStopMulticast(cMulticastGroup* Group);
virtual void Action(); virtual void Action();

View File

@ -64,12 +64,11 @@ void cConnectionIGMP::Welcome()
esyslog("streamdev-server IGMP: GetDevice failed"); esyslog("streamdev-server IGMP: GetDevice failed");
} }
void cConnectionIGMP::Stop() bool cConnectionIGMP::Close()
{ {
if (m_LiveStreamer) { if (m_LiveStreamer)
m_LiveStreamer->Stop(); m_LiveStreamer->Stop();
DELETENULL(m_LiveStreamer); return cServerConnection::Close();
}
} }
cString cConnectionIGMP::ToText() const cString cConnectionIGMP::ToText() const

View File

@ -29,13 +29,13 @@ public:
bool SetChannel(cChannel *Channel, in_addr_t Dst); bool SetChannel(cChannel *Channel, in_addr_t Dst);
virtual void Welcome(void); virtual void Welcome(void);
virtual cString ToText() const; virtual cString ToText() const;
void Stop();
/* Not used here */ /* Not used here */
virtual bool Command(char *Cmd) { return false; } virtual bool Command(char *Cmd) { return false; }
virtual void Attach(void) { if (m_LiveStreamer != NULL) m_LiveStreamer->Attach(); } virtual void Attach(void) { if (m_LiveStreamer != NULL) m_LiveStreamer->Attach(); }
virtual void Detach(void) { if (m_LiveStreamer != NULL) m_LiveStreamer->Detach(); } virtual void Detach(void) { if (m_LiveStreamer != NULL) m_LiveStreamer->Detach(); }
virtual bool Close(void);
virtual bool Abort(void) const; virtual bool Abort(void) const;
}; };