From patchwork Sat Jul 30 14:48:07 2005 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Schmidinger X-Patchwork-Id: 11958 Received: from tiger.cadsoft.de ([217.7.101.210]) by www.linuxtv.org with esmtp (Exim 4.34) id 1DysdH-0002BG-Dx for vdr@linuxtv.org; Sat, 30 Jul 2005 16:48:11 +0200 Received: from raven.cadsoft.de (raven.cadsoft.de [217.7.101.211]) by tiger.cadsoft.de (8.12.7/8.12.7) with ESMTP id j6UEmA8w028491 for ; Sat, 30 Jul 2005 16:48:10 +0200 Received: from [192.168.100.10] (hawk.cadsoft.de [192.168.100.10]) by raven.cadsoft.de (8.13.3/8.13.3) with ESMTP id j6UEm9Xt026888 for ; Sat, 30 Jul 2005 16:48:09 +0200 Message-ID: <42EB9327.10501@cadsoft.de> Date: Sat, 30 Jul 2005 16:48:07 +0200 From: Klaus Schmidinger Organization: CadSoft Computer GmbH User-Agent: Mozilla Thunderbird 1.0.2 (X11/20050317) X-Accept-Language: en MIME-Version: 1.0 To: vdr@linuxtv.org Subject: Re: [vdr] [PATCH] EPG data growing without bounds References: In-Reply-To: X-Greylist: Sender DNS name whitelisted, not delayed by milter-greylist-2.0 (tiger.cadsoft.de [217.7.101.210]); Sat, 30 Jul 2005 16:48:10 +0200 (CEST) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0 (raven.cadsoft.de [192.168.1.1]); Sat, 30 Jul 2005 16:48:10 +0200 (CEST) X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Klaus Schmidinger's VDR List-Id: Klaus Schmidinger's VDR List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jul 2005 14:48:11 -0000 Status: O X-Status: X-Keywords: X-UID: 3843 Olaf Titz wrote: > There is a problem in VDR where the "X" lines in the epg.data file get > duplicated at every restart of VDR (at least?), leading to an ever > growing file and eventual out of memory errors. The following patch > for 1.3.25 (also applies to .27) seems to fix this. It assumes that > the "Components" in the EPG data structures are supposed to be unique, > so it makes them unique (wrt. all fields - if this assumption is wrong > the tComponent::equals() function should be adapted). > > Olaf > > --- epg.h.orig Sat May 28 13:32:36 2005 > +++ epg.h Tue Jul 5 20:33:30 2005 > @@ -28,7 +28,8 @@ > char *description; > cString ToString(void); > bool FromString(const char *s); > - }; > + bool equals(uchar ostream, uchar otype, const char *olanguage, const char *odescription); > +}; > > class cComponents { > private: > @@ -39,7 +40,7 @@ > cComponents(void); > ~cComponents(void); > int NumComponents(void) const { return numComponents; } > - void SetComponent(int Index, const char *s); > + void SetComponent(const char *s); > void SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description); > tComponent *Component(int Index) const { return (Index < numComponents) ? &components[Index] : NULL; } > }; > --- epg.c.orig Sun May 29 12:19:48 2005 > +++ epg.c Tue Jul 5 20:33:29 2005 > @@ -38,6 +38,12 @@ > return n >= 3; > } > > +bool tComponent::equals(uchar ostream, uchar otype, const char *olanguage, const char *odescription) > +{ > + return stream == ostream && type == otype && !strcmp(language, olanguage) > + && ( (description == NULL && odescription == NULL) || !strcmp(description, odescription) ); > +} > + > // --- cComponents ----------------------------------------------------------- > > cComponents::cComponents(void) > @@ -63,8 +69,13 @@ > } > } > > -void cComponents::SetComponent(int Index, const char *s) > +void cComponents::SetComponent(const char *s) > { > + for (int i = 0; i < numComponents; i++) { > + if (!strcmp(s, *components[i].ToString())) > + return; > + } > + int Index = numComponents; > Realloc(Index); > components[Index].FromString(s); > } > @@ -270,7 +281,7 @@ > break; > case 'X': if (!components) > components = new cComponents; > - components->SetComponent(components->NumComponents(), t); > + components->SetComponent(t); > break; > case 'V': SetVps(atoi(t)); > break; > --- eit.c.orig Sat May 28 13:35:55 2005 > +++ eit.c Tue Jul 5 20:11:34 2005 > @@ -198,8 +198,17 @@ > if (1 <= Stream && Stream <= 2 && Type != 0) { > if (!Components) > Components = new cComponents; > + int index = 0; > char buffer[256]; > - Components->SetComponent(Components->NumComponents(), cd->getStreamContent(), cd->getComponentType(), I18nNormalizeLanguageCode(cd->languageCode), cd->description.getText(buffer, sizeof(buffer))); > + cd->description.getText(buffer, sizeof(buffer)); > + const char *lang = I18nNormalizeLanguageCode(cd->languageCode); > + while (index < Components->NumComponents()) { > + tComponent *c = Components->Component(index); > + if (c->equals(Stream, Type, lang, buffer)) > + break; > + index++; > + } > + Components->SetComponent(index, Stream, Type, lang, buffer); > } > } > break; > > === end of patch === Since the code in VDR/eit.c always sets a completely new (and thus consistent) set of components, the only way this can happen is through SVDRP's PUTE command (or while reading epg.data). In order to fix this I believe this should suffice: That way, whenever an event definition is encountered, its components are reset and the new set of components is defined as given. Existing epg.data files that already contain duplicate component entries won't be fixed by this, so either delete them or just wait until those entries get washed out over time. Klaus --- epg.c 2005/06/05 12:17:15 1.35 +++ epg.c 2005/07/30 14:44:54 @@ -298,6 +298,8 @@ if (n == 3 || n == 4) { Event = (cEvent *)Schedule->GetEvent(EventID, StartTime); cEvent *newEvent = NULL; + if (Event) + DELETENULL(Event->components); if (!Event) Event = newEvent = new cEvent(EventID); if (Event) {