[vdr] [ANNOUNCE] VDR version 2.6.4 released

2023-02-18 Thread Klaus Schmidinger

VDR version 2.6.4 is now available at the official VDR GIT archive

  git://git.tvdr.de

You can also get the latest stable version with

  git clone --branch stable/2.6 git://git.tvdr.de/vdr.git

or as a tar archive with

  http://git.tvdr.de/?p=vdr.git;a=snapshot;h=refs/tags/2.6.4;sf=tbz2

This version fixes a few bugs that came up after the release of version 2.6.3.

The changes since version 2.6.3:

- Updated the Italian OSD texts (thanks to Diego Pierotto).
- Fixed restoring the volume at program start (thanks to Matthias Senzel).
- Fixed symmetry of Begin/EndSegmentTransfer() calls in cEIT::cEIT() (thanks to
  Jörg Wendel).
- Added a note to epg.h about not messing with event ids (suggested by Winfried 
Köhler).
- Added a note to vdr.5 about event ids possibly changing when an event moves 
from
  one table to another.
- Fixed initializing cDvbPlayerControl (was broken in version 2.6.3).
- Reverted 'Fixed a possible crash if an editing process is canceled while the 
edited
  recording is being replayed' (introduced in version 2.6.2), because it caused 
a
  deadlock when moving recordings between volumes.
- Fixed a possible crash if an editing process is canceled while the edited 
recording
  is being replayed (new solution).
- Fixed unnecessary interruption of ongoing recordings if timers avoided the 
transfer
  mode receiver device (thanks to Markus Ehrnsperger).
- Revised support for kernel based LIRC driver (thanks to Marko Mäkelä).

Homepage: http://www.tvdr.de
Facebook: https://www.facebook.com/VideoDiskRecorder

Have fun!

Klaus

___
vdr mailing list
vdr@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr


Re: [vdr] [PATCH] Fix cThread related race conditions

2023-02-18 Thread Marko Mäkelä

Wed, Feb 15, 2023 at 05:17:55PM +0100, Klaus Schmidinger wrote:

On 02.02.23 21:56, Patrick Lerda wrote:

...
diff --git a/thread.c b/thread.c
index 93eb8c0..21be7a4 100644
--- a/thread.c
+++ b/thread.c
@@ -312,13 +312,16 @@ bool cThread::Start(void)
   cCondWait::SleepMs(THREAD_STOP_SLEEP);
 }
  if (!active) {
-active = running = true;
-if (pthread_create(, NULL, (void *(*) (void *)), 
(void *)this) == 0) {
-   pthread_detach(childTid); // auto-reap
+pthread_t localTid;
+running = true;
+if (pthread_create(, NULL, (void *(*) (void *)), 
(void *)this) == 0) {
+   pthread_detach(localTid); // auto-reap
+   childTid = localTid;
+   active = true;

[snip]

+ if ((err = pthread_kill(localTid, 0)) != 0) {
 if (err != ESRCH)
LOG_ERROR;
-childTid = 0;
-active = running = false;
+   if (active && childTid == localTid)


localTid was initialized to childTid 4 lines earlier, so what's with 
the "childTid == localTid" check here? Isn't this always true?


cThread::childTid may be modified by another thread that is executing 
cThread::Action() inside cThread::StartThread().


Thinking aloud: Do we need "bool active", or could "childTid!=0" take 
its role?


I see this happens with "address sanitizer". Is there an actual, 
reproducible, real world problem that this patch fixes?


AddressSanitizer only changes some timing characteristics. It should not 
have any direct impact on the possibility of race conditions.


I can agree with your questioning of ThreadSanitizer findings, but I 
think that AddressSanitizer needs to be taken seriously.


For a while, in a multi-threaded piece of software that I maintain, 
AddressSanitizer seemed to issue bogus errors. The reason was a race 
condition around some additional instrumentation to declare memory 
inside a custom allocator as "not allocated", by 
ASAN_POISON_MEMORY_REGION() and ASAN_UNPOISON_MEMORY_REGION(). Ever 
since the code was changed so that we will not shortly poison everything 
and then unpoison the safe bits, but just poison the unsafe bits, 
-fsanitizer=address has only reported real problems.



Are the "atomics" really necessary?


Before C++11, I would think that multiple threads were out of the scope 
of the standard, in the "implementation defined" territory, which is 
kind-of "not even wrong". Now that C++ since the 2011 version covers 
multi-threaded execution, data races are unambiguously "wrong", that is, 
"undefined behaviour".


The way the patch uses std::atomic may be an overkill. While 
std::memory_order_seq_cst (the default) may make little difference to 
ISAs that implement a strong memory model (SPARC, IA-32, AMD64), it can 
be an unnecessary burden on ARM, POWER, RISC-V RVWMO.


If we are only interested in a data field itself and not other memory 
that it may be "protecting" in some other cache line, 
std::memory_order_relaxed should suffice.


If you are running on a single-core or single-socket IA-32 or AMD64 CPU, 
all this should not make much difference. There could already be 
sufficient "compiler barriers" around the code.


Proper use of memory barriers or atomics might fix some rare hangs or 
crashes on startup or shutdown on multi-core ARM system, such as a 
Raspberry Pi.


Race conditions do not always lead to crashes; they could lead to 
slowness or busy loops as well. Just an example: After I fixed a few 
things in the rpihddevice plugin, I can reliably play back or 
fast-forward recordings to the very end, with no premature interruption 
or excessive delays.


I recommend the following to anyone who is working on multi-threaded 
code, especially lock-free data structures and algorithms:


https://en.cppreference.com/w/cpp/atomic/memory_order
https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
https://www.cl.cam.ac.uk/~pes20/ppc-supplemental/test7.pdf

I find it easier to use a mutex or rw-lock to protect shared data 
structures, and to document how the data is being protected. Atomic 
memory access operations usually come into play when there are 
performance bottlenecks that need to be fixed.


Marko

___
vdr mailing list
vdr@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr


Re: [vdr] [PATCH] Use cThread::mutex with absolute cCondVar::TimedWait()

2023-02-18 Thread Marko Mäkelä

Wed, Feb 15, 2023 at 06:01:46PM +0100, Klaus Schmidinger wrote:

On 22.01.23 13:52, Marko Mäkelä wrote:

Hi,

I would propose the following patch, or some equivalent interface that 
would allow cThread::mutex to be used with some cCondVar in derived 
classes:


diff --git a/thread.h b/thread.h
index 16c4bd75..cd1d98ab 100644
--- a/thread.h
+++ b/thread.h
@@ -83,7 +83,9 @@ private:
   bool running;
   pthread_t childTid;
   tThreadId childThreadId;
+protected:
   cMutex mutex;
+private:
   char *description;
   bool lowPriority;
   static tThreadId mainThreadId;


I don't like the idea of exposing that mutex.
If you really need such functionality, please suggest a function that 
does this without exposing the mutex.


An alternative might be to add a member functions to cThread that would 
take a cCondVar& as a parameter and invoke it with the private 
cThread::mutex. But, we can disregard this idea; see below.


[snip]
I did not complete the change to rpihddevice cOmx::Action() yet. We 
may be forced to retain two mutexes after all


You want to expose the cThread::mutex in order to avoid an additional 
mutex in the derived class, but may be forced to retain two mutexes 
after all - what am I missing here?


Meanwhile, I concluded that the only option is to have two mutexes in 
the rpihddevice class cOmx. The cThread::mutex makes calls to the 
ilclient and OMX thread-safe, and a private mutex of cOmx protects
data in callback functions that may be invoked from other threads of 
that external library. An attempt to acquire the cThread::mutex in the 
callback code would lead to a deadlock.


It looks like a simple way to reduce the number of system calls in the 
plugin is to use the POSIX standard pthread_mutex_t and pthread_cond_t 
directly, or via the C++11 std::mutex and std::condition_variable. So, 
there is no pressing need to change anything in the VDR core.


Marko

___
vdr mailing list
vdr@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr