Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: Driver or VDR Problem setting and jusageing cutmarks on Nexus 2.1



On Thu, Jun 03, 2004 at 10:03:21PM +0200, Klaus Schmidinger wrote:
> Juergen Sauer wrote:
> > 
> > Am Donnerstag, 3. Juni 2004 18:29 schrieb Klaus Schmidinger:
> > 
> > > > I tried 1.3.6|9 + 2.6.6|7pre2 tose are running so-la-la, except
> > > > a problem with the fine justage of cut marks.
> > > >
> > > > vdr hangs and is quitted by the watchdog, if I try to move the
> > > > cut-marks.
> > 
> > > Try
> > 
> > >   export LD_ASSUME_KERNEL=2.4.1
> > 
> > > before running VDR.
> > 
> > That's it. Works fine.
> > What's the reason for the 'incomability' ?
> > Is the ld system buggy
> 
> The problem is that kernel 2.6 based systems apparently use the
> NPTL ("Native Posix Thread Library"), which VDR doesn't seem to
> work correctly with.
> 
> Since I myself don't use kernel 2.6 nor the NPTL I can't do any
> testing here. So somebody who uses these will need to look into
> this and find out what's wrong. I've said this on several occasions,
> but apparently there is nobody interested in doing so...

One problem could be signal handling.  For NPTL the signal masks
should be set in such way that for the thread which should receive
a signal unblocks this whereas the other should block it.  Before
any pthread_create() a simple sigprocmask() is usefull to unblock
or block signals in the main process, whereas within the threads
the pthread_sigmask() should be used to protect the threads
from catching signals.

Maybe it would help to modify vdr.c in such a way, that all
handled signals will be unblock in main VDR whereas blocked
in the threads.  Don't know if the patch in the attachment
work, neverthelss you may give it a try.



       Werner

-- 
AC3 loop through sound card http://bitstreamout.sourceforge.net/
Howto http://www.vdr-portal.de/board/thread.php?threadid=1958
------------------------------------------------------------------
 "Having a smoking section in a restaurant is like having
         a  peeing section in a swimming pool." -- Edward Burr
--- thread.c
+++ thread.c	Fri Jun  4 12:33:20 2004
@@ -18,6 +18,8 @@
 #include <unistd.h>
 #include "tools.h"
 
+extern sigset_t TheSigset;	// The signals handled in VDR
+
 // --- cCondVar --------------------------------------------------------------
 
 cCondVar::cCondVar(void)
@@ -149,10 +151,6 @@
 
 cThread::cThread(const char *Description)
 {
-  if (!signalHandlerInstalled) {
-     signal(SIGIO, SignalHandler);
-     signalHandlerInstalled = true;
-     }
   running = false;
   parentTid = childTid = 0;
   description = NULL;
@@ -183,6 +181,17 @@
 
 void *cThread::StartThread(cThread *Thread)
 {
+  (void)pthread_sigmask(SIG_BLOCK, &TheSigset, (sigset_t*)0);
+  if (!signalHandlerInstalled) {
+     sigset_t sigset;
+     sigemptyset(&sigset);
+     sigaddset(&sigset, SIGIO);
+
+     signal(SIGIO, SignalHandler);
+     (void)pthread_sigmask(SIG_UNBLOCK, &sigset, (sigset_t*)0);
+
+     signalHandlerInstalled = true;
+     }
   Thread->childTid = pthread_self();
   if (Thread->description)
      dsyslog("%s thread started (pid=%d, tid=%ld)", Thread->description, getpid(), Thread->childTid);
--- vdr.c
+++ vdr.c	Fri Jun  4 12:33:53 2004
@@ -65,13 +65,84 @@
 
 static int Interrupted = 0;
 
+sigset_t TheSigset;
+
+static struct sigaction SavedSIGHUP;
+static struct sigaction SavedSIGINT;
+static struct sigaction SavedSIGTERM;
+static struct sigaction SavedSIGPIPE;
+static struct sigaction SavedSIGALRM;
+
+static void SetSignal(int sig, struct sigaction &old, sighandler_t handler)
+{
+  do {
+     if (sigaction(sig, NULL, &old) == 0)
+	break;
+     }
+  while (errno == EINTR);
+
+  if (old.sa_handler != handler)
+     {
+     struct sigaction act;
+     sigset_t sigset;
+
+     act.sa_handler = handler;
+     sigemptyset(&act.sa_mask);
+     act.sa_flags = SA_RESTART;
+     if (sig == SIGALRM)
+	act.sa_flags |= SA_ONESHOT;
+     do {
+	if (sigaction(sig, &act, NULL) == 0)
+	   break;
+        }
+     while (errno == EINTR);
+
+     sigaddset(&TheSigset, sig); // Remember the signals
+
+     sigemptyset(&sigset);
+     sigaddset(&sigset, sig);
+     sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+     }
+}
+
+static void ResetSignal(int sig, struct sigaction &old)
+{
+  struct sigaction cur;
+
+  do {
+     if (sigaction(sig, NULL, &cur) == 0)
+	break;
+     }
+  while (errno == EINTR);
+
+  if (old.sa_handler == cur.sa_handler)
+     {
+     do {
+	if (sigaction(sig, &old, NULL) == 0)
+	   break;
+        }
+     while (errno == EINTR);
+     }
+}
+
+static void IgnoreSignal(int sig)
+{
+  sigset_t sigset;
+  sigemptyset(&sigset);
+  sigaddset(&sigset, sig);
+  (void)pthread_sigmask(SIG_BLOCK, &sigset, (sigset_t*)0);
+}
+
 static void SignalHandler(int signum)
 {
   if (signum != SIGPIPE) {
      Interrupted = signum;
      Interface->Interrupt();
      }
-  signal(signum, SignalHandler);
+//
+// Only required if SA_ONESHOT is set in sa_flags
+// signal(signum, SignalHandler);
+//
 }
 
 static void Watchdog(int signum)
@@ -457,13 +528,13 @@
      cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true);
 
   // Signal handlers:
-
-  if (signal(SIGHUP,  SignalHandler) == SIG_IGN) signal(SIGHUP,  SIG_IGN);
-  if (signal(SIGINT,  SignalHandler) == SIG_IGN) signal(SIGINT,  SIG_IGN);
-  if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
-  if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
+  SetSignal(SIGHUP,  SavedSIGHUP,  SignalHandler);
+  SetSignal(SIGINT,  SavedSIGINT,  SignalHandler);
+  SetSignal(SIGTERM, SavedSIGTERM, SignalHandler);
+  SetSignal(SIGPIPE, SavedSIGPIPE, SignalHandler);
   if (WatchdogTimeout > 0)
-     if (signal(SIGALRM, Watchdog)   == SIG_IGN) signal(SIGALRM, SIG_IGN);
+     SetSignal(SIGALRM, SavedSIGALRM, Watchdog);
+  IgnoreSignal(SIGIO);
 
   // Watchdog:
 
@@ -873,6 +944,11 @@
   Setup.Save();
   cDevice::Shutdown();
   PluginManager.Shutdown(true);
+  ResetSignal(SIGHUP,  SavedSIGHUP);
+  ResetSignal(SIGINT,  SavedSIGINT);
+  ResetSignal(SIGTERM, SavedSIGTERM);
+  ResetSignal(SIGPIPE, SavedSIGPIPE);
+  ResetSignal(SIGALRM, SavedSIGALRM);
   ReportEpgBugFixStats();
   if (WatchdogTimeout > 0)
      dsyslog("max. latency time %d seconds", MaxLatencyTime);

Home | Main Index | Thread Index