mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Changed thread handling to make it work with NPTL
This commit is contained in:
		@@ -177,6 +177,7 @@ Stefan Huelswitt <huels@iname.com>
 | 
			
		||||
 for fixing an uninitialized variable in cDisplayChannel
 | 
			
		||||
 for fixing a possible access of invalid file handles in cSIProcessor::Action()
 | 
			
		||||
 for fixing extracting the ES data in cDvbDevice::StillPicture()
 | 
			
		||||
 for changing thread handling to make it work with NPTL ("Native Posix Thread Library")
 | 
			
		||||
 | 
			
		||||
Ulrich R<>der <roeder@efr-net.de>
 | 
			
		||||
 for pointing out that there are channels that have a symbol rate higher than
 | 
			
		||||
@@ -210,6 +211,7 @@ Andreas Schultz <aschultz@warp10.net>
 | 
			
		||||
 for changing C++ style comments in libdtv into C style to avoid warnings in gcc 3.x
 | 
			
		||||
 for implementing the TerrestrialDeliverySystemDescriptor in libdtv
 | 
			
		||||
 for fixing setting the locking pid after a timed wait
 | 
			
		||||
 for changing thread handling to make it work with NPTL ("Native Posix Thread Library")
 | 
			
		||||
 | 
			
		||||
Aaron Holtzman
 | 
			
		||||
 for writing 'ac3dec'
 | 
			
		||||
@@ -243,6 +245,7 @@ Werner Fink <werner@suse.de>
 | 
			
		||||
 for replacing the 'for' loops in StripAudioPackets() with memset() calls
 | 
			
		||||
 for modifying handling of audio packets in cDvbPlayer for better sync with external
 | 
			
		||||
 AC3 replay
 | 
			
		||||
 for changing thread handling to make it work with NPTL ("Native Posix Thread Library")
 | 
			
		||||
 | 
			
		||||
Rolf Hakenes <hakenes@hippomi.de>
 | 
			
		||||
 for providing 'libdtv' and adapting the EIT mechanisms to it
 | 
			
		||||
@@ -758,6 +761,7 @@ Karim Afifi <karim.afifi@free.fr>
 | 
			
		||||
 | 
			
		||||
Jon Burgess <mplayer@jburgess.uklinux.net>
 | 
			
		||||
 for pointing out a problem with NPTL ("Native Posix Thread Library")
 | 
			
		||||
 for changing thread handling to make it work with NPTL ("Native Posix Thread Library")
 | 
			
		||||
 | 
			
		||||
Thomas Schmidt <thomas.schmidt@in.stud.tu-ilmenau.de>
 | 
			
		||||
 for reporting a crash when cancelling a newly created timer
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								HISTORY
									
									
									
									
									
								
							@@ -2433,3 +2433,8 @@ Video Disk Recorder Revision History
 | 
			
		||||
  full (suggested by Emil Naepflein).
 | 
			
		||||
- Channel IDs are now checked when reading 'channels.conf' to avoid later
 | 
			
		||||
  problems with timers.
 | 
			
		||||
 | 
			
		||||
2003-10-18: Version 1.3.0
 | 
			
		||||
 | 
			
		||||
- Changed thread handling to make it work with NPTL ("Native Posix Thread Library").
 | 
			
		||||
  Thanks to Jon Burgess, Andreas Schultz, Werner Fink and Stefan Huelswitt.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								INSTALL
									
									
									
									
									
								
							@@ -1,19 +1,9 @@
 | 
			
		||||
Installation of the Video Disk Recorder
 | 
			
		||||
---------------------------------------
 | 
			
		||||
 | 
			
		||||
Version 1.2
 | 
			
		||||
Version 1.3
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
IMPORTANT NOTE:
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
VDR currently doesn't work with NPTL ("Native Posix Thread Library").
 | 
			
		||||
Either don't use NPTL, or set the environment variable
 | 
			
		||||
 | 
			
		||||
  LD_ASSUME_KERNEL=2.4.1
 | 
			
		||||
  
 | 
			
		||||
before running VDR.
 | 
			
		||||
 | 
			
		||||
Compiling and running the program:
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								config.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: config.h 1.176 2003/10/17 12:35:23 kls Exp $
 | 
			
		||||
 * $Id: config.h 1.177 2003/10/18 11:14:33 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CONFIG_H
 | 
			
		||||
@@ -19,8 +19,8 @@
 | 
			
		||||
#include "device.h"
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
#define VDRVERSION  "1.2.6pre1"
 | 
			
		||||
#define VDRVERSNUM   10206  // Version * 10000 + Major * 100 + Minor
 | 
			
		||||
#define VDRVERSION  "1.3.0"
 | 
			
		||||
#define VDRVERSNUM   10300  // Version * 10000 + Major * 100 + Minor
 | 
			
		||||
 | 
			
		||||
#define MAXPRIORITY 99
 | 
			
		||||
#define MAXLIFETIME 99
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								ringbuffer.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ringbuffer.c
									
									
									
									
									
								
							@@ -7,7 +7,7 @@
 | 
			
		||||
 * Parts of this file were inspired by the 'ringbuffy.c' from the
 | 
			
		||||
 * LinuxDVB driver (see linuxtv.org).
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: ringbuffer.c 1.17 2003/05/12 17:38:11 kls Exp $
 | 
			
		||||
 * $Id: ringbuffer.c 1.18 2003/10/18 10:29:25 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "ringbuffer.h"
 | 
			
		||||
@@ -75,7 +75,7 @@ cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics)
 | 
			
		||||
{
 | 
			
		||||
  margin = Margin;
 | 
			
		||||
  buffer = NULL;
 | 
			
		||||
  getThreadPid = -1;
 | 
			
		||||
  getThreadTid = 0;
 | 
			
		||||
  if (Size > 1) { // 'Size - 1' must not be 0!
 | 
			
		||||
     buffer = MALLOC(uchar, Size);
 | 
			
		||||
     if (!buffer)
 | 
			
		||||
@@ -125,7 +125,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
 | 
			
		||||
        int percent = maxFill * 100 / (Size() - 1) / 5 * 5;
 | 
			
		||||
        if (abs(lastPercent - percent) >= 5) {
 | 
			
		||||
           if (percent > 75)
 | 
			
		||||
              dsyslog("buffer usage: %d%% (pid=%d)", percent, getThreadPid);
 | 
			
		||||
              dsyslog("buffer usage: %d%% (tid=%ld)", percent, getThreadTid);
 | 
			
		||||
           lastPercent = percent;
 | 
			
		||||
           }
 | 
			
		||||
        }
 | 
			
		||||
@@ -159,8 +159,8 @@ uchar *cRingBufferLinear::Get(int &Count)
 | 
			
		||||
{
 | 
			
		||||
  uchar *p = NULL;
 | 
			
		||||
  Lock();
 | 
			
		||||
  if (getThreadPid < 0)
 | 
			
		||||
     getThreadPid = getpid();
 | 
			
		||||
  if (getThreadTid <= 0)
 | 
			
		||||
     getThreadTid = pthread_self();
 | 
			
		||||
  int rest = Size() - tail;
 | 
			
		||||
  if (rest < margin && head < tail) {
 | 
			
		||||
     int t = margin - rest;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: ringbuffer.h 1.12 2003/05/12 17:35:10 kls Exp $
 | 
			
		||||
 * $Id: ringbuffer.h 1.13 2003/10/18 10:29:25 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __RINGBUFFER_H
 | 
			
		||||
@@ -46,7 +46,7 @@ private:
 | 
			
		||||
  int margin, head, tail;
 | 
			
		||||
  int lastGet;
 | 
			
		||||
  uchar *buffer;
 | 
			
		||||
  pid_t getThreadPid;
 | 
			
		||||
  pthread_t getThreadTid;
 | 
			
		||||
public:
 | 
			
		||||
  cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false);
 | 
			
		||||
    ///< Creates a linear ring buffer.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								thread.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								thread.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: thread.c 1.25 2003/05/18 12:45:13 kls Exp $
 | 
			
		||||
 * $Id: thread.c 1.26 2003/10/18 10:29:25 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "thread.h"
 | 
			
		||||
@@ -30,7 +30,7 @@ cCondVar::~cCondVar()
 | 
			
		||||
 | 
			
		||||
void cCondVar::Wait(cMutex &Mutex)
 | 
			
		||||
{
 | 
			
		||||
  if (Mutex.locked && Mutex.lockingPid == getpid()) {
 | 
			
		||||
  if (Mutex.locked && pthread_equal(Mutex.lockingTid, pthread_self())) {
 | 
			
		||||
     int locked = Mutex.locked;
 | 
			
		||||
     Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_wait
 | 
			
		||||
                       // does an implizit unlock of the mutex
 | 
			
		||||
@@ -43,7 +43,7 @@ bool cCondVar::TimedWait(cMutex &Mutex, int TimeoutMs)
 | 
			
		||||
{
 | 
			
		||||
  bool r = true; // true = condition signaled false = timeout
 | 
			
		||||
 | 
			
		||||
  if (Mutex.locked && Mutex.lockingPid == getpid()) {
 | 
			
		||||
  if (Mutex.locked && pthread_equal(Mutex.lockingTid, pthread_self())) {
 | 
			
		||||
     struct timeval now;                   // unfortunately timedwait needs the absolute time, not the delta :-(
 | 
			
		||||
     if (gettimeofday(&now, NULL) == 0) {  // get current time
 | 
			
		||||
        now.tv_usec += TimeoutMs * 1000;   // add the timeout
 | 
			
		||||
@@ -61,7 +61,7 @@ bool cCondVar::TimedWait(cMutex &Mutex, int TimeoutMs)
 | 
			
		||||
        if (pthread_cond_timedwait(&cond, &Mutex.mutex, &abstime) == ETIMEDOUT)
 | 
			
		||||
           r = false;
 | 
			
		||||
        Mutex.locked = locked;
 | 
			
		||||
        Mutex.lockingPid = getpid();
 | 
			
		||||
        Mutex.lockingTid = pthread_self();
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  return r;
 | 
			
		||||
@@ -83,7 +83,7 @@ void cCondVar::Signal(void)
 | 
			
		||||
 | 
			
		||||
cMutex::cMutex(void)
 | 
			
		||||
{
 | 
			
		||||
  lockingPid = 0;
 | 
			
		||||
  lockingTid = 0;
 | 
			
		||||
  locked = 0;
 | 
			
		||||
  pthread_mutex_init(&mutex, NULL);
 | 
			
		||||
}
 | 
			
		||||
@@ -95,9 +95,9 @@ cMutex::~cMutex()
 | 
			
		||||
 | 
			
		||||
void cMutex::Lock(void)
 | 
			
		||||
{
 | 
			
		||||
  if (getpid() != lockingPid || !locked) {
 | 
			
		||||
  if (!pthread_equal(lockingTid, pthread_self()) || !locked) {
 | 
			
		||||
     pthread_mutex_lock(&mutex);
 | 
			
		||||
     lockingPid = getpid();
 | 
			
		||||
     lockingTid = pthread_self();
 | 
			
		||||
     }
 | 
			
		||||
  locked++;
 | 
			
		||||
}
 | 
			
		||||
@@ -105,7 +105,7 @@ void cMutex::Lock(void)
 | 
			
		||||
void cMutex::Unlock(void)
 | 
			
		||||
{
 | 
			
		||||
 if (!--locked) {
 | 
			
		||||
    lockingPid = 0;
 | 
			
		||||
    lockingTid = 0;
 | 
			
		||||
    pthread_mutex_unlock(&mutex);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -125,7 +125,7 @@ cThread::cThread(void)
 | 
			
		||||
     signalHandlerInstalled = true;
 | 
			
		||||
     }
 | 
			
		||||
  running = false;
 | 
			
		||||
  parentPid = threadPid = 0;
 | 
			
		||||
  parentTid = childTid = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cThread::~cThread()
 | 
			
		||||
@@ -139,8 +139,9 @@ void cThread::SignalHandler(int signum)
 | 
			
		||||
 | 
			
		||||
void *cThread::StartThread(cThread *Thread)
 | 
			
		||||
{
 | 
			
		||||
  Thread->threadPid = getpid();
 | 
			
		||||
  Thread->childTid = pthread_self();
 | 
			
		||||
  Thread->Action();
 | 
			
		||||
  Thread->childTid = 0;
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -148,9 +149,9 @@ bool cThread::Start(void)
 | 
			
		||||
{
 | 
			
		||||
  if (!running) {
 | 
			
		||||
     running = true;
 | 
			
		||||
     parentPid = getpid();
 | 
			
		||||
     pthread_create(&thread, NULL, (void *(*) (void *))&StartThread, (void *)this);
 | 
			
		||||
     pthread_setschedparam(thread, SCHED_RR, 0);
 | 
			
		||||
     parentTid = pthread_self();
 | 
			
		||||
     pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this);
 | 
			
		||||
     pthread_setschedparam(childTid, SCHED_RR, 0);
 | 
			
		||||
     usleep(10000); // otherwise calling Active() immediately after Start() causes a "pure virtual method called" error
 | 
			
		||||
     }
 | 
			
		||||
  return true; //XXX return value of pthread_create()???
 | 
			
		||||
@@ -158,12 +159,21 @@ bool cThread::Start(void)
 | 
			
		||||
 | 
			
		||||
bool cThread::Active(void)
 | 
			
		||||
{
 | 
			
		||||
  if (threadPid) {
 | 
			
		||||
     if (kill(threadPid, SIGIO) < 0) { // couldn't find another way of checking whether the thread is still running - any ideas?
 | 
			
		||||
        if (errno == ESRCH)
 | 
			
		||||
           threadPid = 0;
 | 
			
		||||
        else
 | 
			
		||||
  if (childTid) {
 | 
			
		||||
     //
 | 
			
		||||
     // Single UNIX Spec v2 says:
 | 
			
		||||
     //
 | 
			
		||||
     // The pthread_kill() function is used to request
 | 
			
		||||
     // that a signal be delivered to the specified thread.
 | 
			
		||||
     //
 | 
			
		||||
     // As in kill(), if sig is zero, error checking is
 | 
			
		||||
     // performed but no signal is actually sent.
 | 
			
		||||
     //
 | 
			
		||||
     int err;
 | 
			
		||||
     if ((err = pthread_kill(childTid, 0)) != 0) {
 | 
			
		||||
        if (err != ESRCH)
 | 
			
		||||
           LOG_ERROR;
 | 
			
		||||
        childTid = 0;
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        return true;
 | 
			
		||||
@@ -180,14 +190,14 @@ void cThread::Cancel(int WaitSeconds)
 | 
			
		||||
            return;
 | 
			
		||||
         usleep(10000);
 | 
			
		||||
         }
 | 
			
		||||
     esyslog("ERROR: thread %d won't end (waited %d seconds) - cancelling it...", threadPid, WaitSeconds);
 | 
			
		||||
     esyslog("ERROR: thread %ld won't end (waited %d seconds) - cancelling it...", childTid, WaitSeconds);
 | 
			
		||||
     }
 | 
			
		||||
  pthread_cancel(thread);
 | 
			
		||||
  pthread_cancel(childTid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cThread::WakeUp(void)
 | 
			
		||||
{
 | 
			
		||||
  kill(parentPid, SIGIO); // makes any waiting 'select()' call return immediately
 | 
			
		||||
  pthread_kill(parentTid, SIGIO); // makes any waiting 'select()' call return immediately
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cThread::EmergencyExit(bool Request)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								thread.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								thread.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: thread.h 1.15 2003/05/03 14:03:36 kls Exp $
 | 
			
		||||
 * $Id: thread.h 1.16 2003/10/18 10:29:25 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __THREAD_H
 | 
			
		||||
@@ -32,7 +32,7 @@ class cMutex {
 | 
			
		||||
  friend class cCondVar;
 | 
			
		||||
private:
 | 
			
		||||
  pthread_mutex_t mutex;
 | 
			
		||||
  pid_t lockingPid;
 | 
			
		||||
  pthread_t lockingTid;
 | 
			
		||||
  int locked;
 | 
			
		||||
public:
 | 
			
		||||
  cMutex(void);
 | 
			
		||||
@@ -44,9 +44,8 @@ public:
 | 
			
		||||
class cThread {
 | 
			
		||||
  friend class cThreadLock;
 | 
			
		||||
private:
 | 
			
		||||
  pthread_t thread;
 | 
			
		||||
  pthread_t parentTid, childTid;
 | 
			
		||||
  cMutex mutex;
 | 
			
		||||
  pid_t parentPid, threadPid;
 | 
			
		||||
  bool running;
 | 
			
		||||
  static bool emergencyExitRequested;
 | 
			
		||||
  static bool signalHandlerInstalled;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user