diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 6893a025..beeb492e 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -3598,6 +3598,7 @@ Stefan Herdler for reporting the index file of a recording not being regenerated in case it is present, but empty for reporting a missing check for self-assignment in the move assignment operator + for modifying handling channel names with source to make it thread safe Tobias Faust for the original "jumpingseconds" patch diff --git a/HISTORY b/HISTORY index 166e95f1..fe735ac6 100644 --- a/HISTORY +++ b/HISTORY @@ -9887,8 +9887,10 @@ Video Disk Recorder Revision History - Fixed possible duplicate component entries in the info of an ongoing recording (reported by Christoph Haubrich). -2024-03-01: +2024-03-02: - Fixed the move assignment operator to check for self-assignment (suggested by Stefan Herdler). - Added missing initialization of cChannel::nameSourceMode (thanks to Winfried Köhler). +- Modified handling channel names with source to make it thread safe (thanks to + Stefan Herdler). diff --git a/channels.c b/channels.c index 74e95f54..eacd7603 100644 --- a/channels.c +++ b/channels.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 5.2 2024/03/01 14:31:49 kls Exp $ + * $Id: channels.c 5.3 2024/03/02 16:21:16 kls Exp $ */ #include "channels.h" @@ -60,7 +60,6 @@ cChannel::cChannel(void) provider = strdup(""); portalName = strdup(""); memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__); - nameSourceMode = 0; parameters = ""; modification = CHANNELMOD_NONE; seen = 0; @@ -98,23 +97,32 @@ cChannel& cChannel::operator= (const cChannel &Channel) provider = strcpyrealloc(provider, Channel.provider); portalName = strcpyrealloc(portalName, Channel.portalName); memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__); - nameSource = NULL; // these will be recalculated automatically - nameSourceMode = 0; - shortNameSource = NULL; + UpdateNameSource(); parameters = Channel.parameters; return *this; } +void cChannel::UpdateNameSource(void) +{ + if (Setup.ShowChannelNamesWithSource == 0) { + nameSource = NULL; + shortNameSource = NULL; + return; + } + + if (Setup.ShowChannelNamesWithSource == 1) + nameSource = cString::sprintf("%s (%c)", name, cSource::ToChar(source)); + else + nameSource = cString::sprintf("%s (%s)", name, *cSource::ToString(source)); + + shortNameSource = cString::sprintf("%s (%c)", shortName, cSource::ToChar(source)); +} + const char *cChannel::Name(void) const { if (Setup.ShowChannelNamesWithSource && !groupSep) { - if (isempty(nameSource) || nameSourceMode != Setup.ShowChannelNamesWithSource) { - if (Setup.ShowChannelNamesWithSource == 1) - nameSource = cString::sprintf("%s (%c)", name, cSource::ToChar(source)); - else - nameSource = cString::sprintf("%s (%s)", name, *cSource::ToString(source)); - } - return nameSource; + if (!isempty(nameSource)) + return nameSource; } return name; } @@ -124,9 +132,8 @@ const char *cChannel::ShortName(bool OrName) const if (OrName && isempty(shortName)) return Name(); if (Setup.ShowChannelNamesWithSource && !groupSep) { - if (isempty(shortNameSource)) - shortNameSource = cString::sprintf("%s (%c)", shortName, cSource::ToChar(source)); - return shortNameSource; + if (!isempty(shortNameSource)) + return shortNameSource; } return shortName; } @@ -204,9 +211,7 @@ bool cChannel::SetTransponderData(int Source, int Frequency, int Srate, const ch srate = Srate; parameters = Parameters; schedule = NULL; - nameSource = NULL; - nameSourceMode = 0; - shortNameSource = NULL; + UpdateNameSource(); if (Number() && !Quiet) { dsyslog("changing transponder data of channel %d (%s) from %s to %s", Number(), name, *OldTransponderData, *TransponderDataToString()); modification |= CHANNELMOD_TRANSP; @@ -271,15 +276,12 @@ bool cChannel::SetName(const char *Name, const char *ShortName, const char *Prov dsyslog("changing name of channel %d from '%s,%s;%s' to '%s,%s;%s'", Number(), name, shortName, provider, Name, ShortName, Provider); modification |= CHANNELMOD_NAME; } - if (nn) { + if (nn) name = strcpyrealloc(name, Name); - nameSource = NULL; - nameSourceMode = 0; - } - if (ns) { + if (ns) shortName = strcpyrealloc(shortName, ShortName); - shortNameSource = NULL; - } + if (nn || ns) + UpdateNameSource(); if (np) provider = strcpyrealloc(provider, Provider); return true; @@ -805,9 +807,7 @@ bool cChannel::Parse(const char *s) free(tpidbuf); free(caidbuf); free(namebuf); - nameSource = NULL; - nameSourceMode = 0; - shortNameSource = NULL; + UpdateNameSource(); if (!GetChannelID().Valid()) { esyslog("ERROR: channel data results in invalid ID!"); return false; diff --git a/channels.h b/channels.h index 25ddc3d1..5c61a66f 100644 --- a/channels.h +++ b/channels.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.h 5.2 2021/05/21 09:38:34 kls Exp $ + * $Id: channels.h 5.3 2024/03/02 16:21:16 kls Exp $ */ #ifndef __CHANNELS_H @@ -87,6 +87,7 @@ class cChannels; class cChannel : public cListObject { friend class cSchedules; friend class cMenuEditChannel; + friend class cMenuSetupMisc; friend class cDvbSourceParam; private: static cString ToText(const cChannel *Channel); @@ -123,9 +124,8 @@ private: int number; // Sequence number assigned on load bool groupSep; int __EndData__; - mutable cString nameSource; - mutable int nameSourceMode; - mutable cString shortNameSource; + cString nameSource; + cString shortNameSource; cString parameters; mutable int modification; time_t seen; // When this channel was last seen in the SDT of its transponder @@ -133,6 +133,7 @@ private: cLinkChannels *linkChannels; cChannel *refChannel; cString TransponderDataToString(void) const; + void UpdateNameSource(void); public: cChannel(void); cChannel(const cChannel &Channel);