diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 3c86eee6..370cd140 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -177,6 +177,7 @@ Stefan Huelswitt 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 for pointing out that there are channels that have a symbol rate higher than @@ -210,6 +211,7 @@ Andreas Schultz 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 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 for providing 'libdtv' and adapting the EIT mechanisms to it @@ -758,6 +761,7 @@ Karim Afifi Jon Burgess 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 for reporting a crash when cancelling a newly created timer diff --git a/HISTORY b/HISTORY index 17fa92fe..f65a97ab 100644 --- a/HISTORY +++ b/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. diff --git a/INSTALL b/INSTALL index 987d5a5a..88546ea7 100644 --- a/INSTALL +++ b/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: ---------------------------------- diff --git a/config.h b/config.h index a5b33541..9125d2c8 100644 --- a/config.h +++ b/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 diff --git a/ringbuffer.c b/ringbuffer.c index 2cf9d75d..5eee41ec 100644 --- a/ringbuffer.c +++ b/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; diff --git a/ringbuffer.h b/ringbuffer.h index 15063454..ca5b2069 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -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. diff --git a/thread.c b/thread.c index 5fbcfd88..f30e7cc1 100644 --- a/thread.c +++ b/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) diff --git a/thread.h b/thread.h index 05997424..65c0d7c9 100644 --- a/thread.h +++ b/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;