From patchwork Thu Feb 2 22:16:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Lerda X-Patchwork-Id: 89555 Received: from [127.0.0.1] by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1pNhsr-00EODs-Uq; Thu, 02 Feb 2023 22:16:45 +0000 Received: from zkko.ml ([78.198.177.192] helo=mail.zkko.ml) by www.linuxtv.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pNhsp-00EODl-IY for vdr@linuxtv.org; Thu, 02 Feb 2023 22:16:44 +0000 Received: from over.fork.zz (over.fork.zz [192.168.0.155]) by mail.zkko.ml (8.16.1/8.16.1) with ESMTPS id 312MGfYe031976 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=FAIL); Thu, 2 Feb 2023 23:16:41 +0100 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=zkko.ml; s=mail; t=1675376202; bh=/urjOm/b3NKuG/dYPJSxx1HGueo=; h=From:To:Cc:Subject:Date:From; b=Tg9lQOAhv04CS1o55I9ZlSYpK5ySaExW6UQ65reamHGjUdJVU3BxXPbqG8MRrN2Xs Ii+O6cONvn96ZddFhHDeqvfurYAwbptwAfVOENejxpl54zk8Uhb+/DMYHFO26zq2mR HS5s3z/ohUvIUnuVdd7VjQrpZ7pF4yLARBRy3JNY= Received: from over.fork.zz (localhost.fork.zz [127.0.0.1]) by over.fork.zz (8.16.1/8.16.1) with ESMTPS id 312MGe3D023493 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Thu, 2 Feb 2023 23:16:41 +0100 Received: (from patrick@localhost) by over.fork.zz (8.16.1/8.16.1/Submit) id 312MGeuq023492; Thu, 2 Feb 2023 23:16:40 +0100 X-Authentication-Warning: over.fork.zz: patrick set sender to patrick9876@free.fr using -f From: Patrick Lerda To: vdr@linuxtv.org Date: Thu, 2 Feb 2023 23:16:08 +0100 Message-Id: X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 X-LSpam-Score: -1.6 (-) X-LSpam-Report: No, score=-1.6 required=5.0 tests=BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001 autolearn=no autolearn_force=no Subject: [vdr] [PATCH] Add thread safety to cRingBufferLinear X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: VDR Mailing List Errors-To: vdr-bounces@linuxtv.org Sender: "vdr" Beside preventing crashes with vdr-2.6.3 this is required to get vdr to work properly with the gcc thread sanitizer. --- ringbuffer.c | 18 +++++++++++++++++- ringbuffer.h | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ringbuffer.c b/ringbuffer.c index 902c887..1c24df2 100644 --- a/ringbuffer.c +++ b/ringbuffer.c @@ -210,12 +210,16 @@ int cRingBufferLinear::DataReady(const uchar *Data, int Count) int cRingBufferLinear::Available(void) { + Lock(); int diff = head - tail; - return (diff >= 0) ? diff : Size() + diff - margin; + int available = (diff >= 0) ? diff : Size() + diff - margin; + Unlock(); + return available; } void cRingBufferLinear::Clear(void) { + Lock(); int Head = head; tail = Head; #ifdef DEBUGRINGBUFFERS @@ -224,11 +228,13 @@ void cRingBufferLinear::Clear(void) lastPut = lastGet = -1; #endif maxFill = 0; + Unlock(); EnablePut(); } int cRingBufferLinear::Read(int FileHandle, int Max) { + Lock(); int Tail = tail; int diff = Tail - head; int free = (diff > 0) ? diff - 1 : Size() - head; @@ -259,6 +265,7 @@ int cRingBufferLinear::Read(int FileHandle, int Max) lastHead = head; lastPut = Count; #endif + Unlock(); EnableGet(); if (free == 0) WaitForPut(); @@ -267,6 +274,7 @@ int cRingBufferLinear::Read(int FileHandle, int Max) int cRingBufferLinear::Read(cUnbufferedFile *File, int Max) { + Lock(); int Tail = tail; int diff = Tail - head; int free = (diff > 0) ? diff - 1 : Size() - head; @@ -297,6 +305,7 @@ int cRingBufferLinear::Read(cUnbufferedFile *File, int Max) lastHead = head; lastPut = Count; #endif + Unlock(); EnableGet(); if (free == 0) WaitForPut(); @@ -306,6 +315,7 @@ int cRingBufferLinear::Read(cUnbufferedFile *File, int Max) int cRingBufferLinear::Put(const uchar *Data, int Count) { if (Count > 0) { + Lock(); int Tail = tail; int rest = Size() - head; int diff = Tail - head; @@ -336,6 +346,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) lastHead = head; lastPut = Count; #endif + Unlock(); EnableGet(); if (Count == 0) WaitForPut(); @@ -345,6 +356,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) uchar *cRingBufferLinear::Get(int &Count) { + Lock(); int Head = head; if (getThreadTid <= 0) getThreadTid = cThread::ThreadId(); @@ -362,14 +374,17 @@ uchar *cRingBufferLinear::Get(int &Count) uchar *p = buffer + tail; if ((cont = DataReady(p, cont)) > 0) { Count = gotten = cont; + Unlock(); return p; } + Unlock(); WaitForGet(); return NULL; } void cRingBufferLinear::Del(int Count) { + Lock(); if (Count > gotten) { esyslog("ERROR: invalid Count in cRingBufferLinear::Del: %d (limited to %d)", Count, gotten); Count = gotten; @@ -387,6 +402,7 @@ void cRingBufferLinear::Del(int Count) lastTail = tail; lastGet = Count; #endif + Unlock(); } // --- cFrame ---------------------------------------------------------------- diff --git a/ringbuffer.h b/ringbuffer.h index 746fc51..cbaa12c 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -58,10 +58,13 @@ public: static void PrintDebugRBL(void); #endif private: + cMutex mutex; int margin, head, tail; int gotten; uchar *buffer; char *description; + void Lock(void) { mutex.Lock(); } + void Unlock(void) { mutex.Unlock(); } protected: virtual int DataReady(const uchar *Data, int Count); ///< By default a ring buffer has data ready as soon as there are at least