1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Changed thread handling to make it work with NPTL

This commit is contained in:
Klaus Schmidinger 2003-10-18 11:14:33 +02:00
parent f1a4d067be
commit 15816ee8e4
8 changed files with 54 additions and 46 deletions

View File

@ -177,6 +177,7 @@ Stefan Huelswitt <huels@iname.com>
for fixing an uninitialized variable in cDisplayChannel for fixing an uninitialized variable in cDisplayChannel
for fixing a possible access of invalid file handles in cSIProcessor::Action() for fixing a possible access of invalid file handles in cSIProcessor::Action()
for fixing extracting the ES data in cDvbDevice::StillPicture() 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> Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than 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 changing C++ style comments in libdtv into C style to avoid warnings in gcc 3.x
for implementing the TerrestrialDeliverySystemDescriptor in libdtv for implementing the TerrestrialDeliverySystemDescriptor in libdtv
for fixing setting the locking pid after a timed wait 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 Aaron Holtzman
for writing 'ac3dec' for writing 'ac3dec'
@ -243,6 +245,7 @@ Werner Fink <werner@suse.de>
for replacing the 'for' loops in StripAudioPackets() with memset() calls for replacing the 'for' loops in StripAudioPackets() with memset() calls
for modifying handling of audio packets in cDvbPlayer for better sync with external for modifying handling of audio packets in cDvbPlayer for better sync with external
AC3 replay AC3 replay
for changing thread handling to make it work with NPTL ("Native Posix Thread Library")
Rolf Hakenes <hakenes@hippomi.de> Rolf Hakenes <hakenes@hippomi.de>
for providing 'libdtv' and adapting the EIT mechanisms to it 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> Jon Burgess <mplayer@jburgess.uklinux.net>
for pointing out a problem with NPTL ("Native Posix Thread Library") 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> Thomas Schmidt <thomas.schmidt@in.stud.tu-ilmenau.de>
for reporting a crash when cancelling a newly created timer for reporting a crash when cancelling a newly created timer

View File

@ -2433,3 +2433,8 @@ Video Disk Recorder Revision History
full (suggested by Emil Naepflein). full (suggested by Emil Naepflein).
- Channel IDs are now checked when reading 'channels.conf' to avoid later - Channel IDs are now checked when reading 'channels.conf' to avoid later
problems with timers. 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
View File

@ -1,19 +1,9 @@
Installation of the Video Disk Recorder 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: Compiling and running the program:
---------------------------------- ----------------------------------

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __CONFIG_H
@ -19,8 +19,8 @@
#include "device.h" #include "device.h"
#include "tools.h" #include "tools.h"
#define VDRVERSION "1.2.6pre1" #define VDRVERSION "1.3.0"
#define VDRVERSNUM 10206 // Version * 10000 + Major * 100 + Minor #define VDRVERSNUM 10300 // Version * 10000 + Major * 100 + Minor
#define MAXPRIORITY 99 #define MAXPRIORITY 99
#define MAXLIFETIME 99 #define MAXLIFETIME 99

View File

@ -7,7 +7,7 @@
* Parts of this file were inspired by the 'ringbuffy.c' from the * Parts of this file were inspired by the 'ringbuffy.c' from the
* LinuxDVB driver (see linuxtv.org). * 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" #include "ringbuffer.h"
@ -75,7 +75,7 @@ cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics)
{ {
margin = Margin; margin = Margin;
buffer = NULL; buffer = NULL;
getThreadPid = -1; getThreadTid = 0;
if (Size > 1) { // 'Size - 1' must not be 0! if (Size > 1) { // 'Size - 1' must not be 0!
buffer = MALLOC(uchar, Size); buffer = MALLOC(uchar, Size);
if (!buffer) if (!buffer)
@ -125,7 +125,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
int percent = maxFill * 100 / (Size() - 1) / 5 * 5; int percent = maxFill * 100 / (Size() - 1) / 5 * 5;
if (abs(lastPercent - percent) >= 5) { if (abs(lastPercent - percent) >= 5) {
if (percent > 75) if (percent > 75)
dsyslog("buffer usage: %d%% (pid=%d)", percent, getThreadPid); dsyslog("buffer usage: %d%% (tid=%ld)", percent, getThreadTid);
lastPercent = percent; lastPercent = percent;
} }
} }
@ -159,8 +159,8 @@ uchar *cRingBufferLinear::Get(int &Count)
{ {
uchar *p = NULL; uchar *p = NULL;
Lock(); Lock();
if (getThreadPid < 0) if (getThreadTid <= 0)
getThreadPid = getpid(); getThreadTid = pthread_self();
int rest = Size() - tail; int rest = Size() - tail;
if (rest < margin && head < tail) { if (rest < margin && head < tail) {
int t = margin - rest; int t = margin - rest;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __RINGBUFFER_H
@ -46,7 +46,7 @@ private:
int margin, head, tail; int margin, head, tail;
int lastGet; int lastGet;
uchar *buffer; uchar *buffer;
pid_t getThreadPid; pthread_t getThreadTid;
public: public:
cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false); cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false);
///< Creates a linear ring buffer. ///< Creates a linear ring buffer.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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" #include "thread.h"
@ -30,7 +30,7 @@ cCondVar::~cCondVar()
void cCondVar::Wait(cMutex &Mutex) void cCondVar::Wait(cMutex &Mutex)
{ {
if (Mutex.locked && Mutex.lockingPid == getpid()) { if (Mutex.locked && pthread_equal(Mutex.lockingTid, pthread_self())) {
int locked = Mutex.locked; int locked = Mutex.locked;
Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_wait Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_wait
// does an implizit unlock of the mutex // 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 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 :-( struct timeval now; // unfortunately timedwait needs the absolute time, not the delta :-(
if (gettimeofday(&now, NULL) == 0) { // get current time if (gettimeofday(&now, NULL) == 0) { // get current time
now.tv_usec += TimeoutMs * 1000; // add the timeout 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) if (pthread_cond_timedwait(&cond, &Mutex.mutex, &abstime) == ETIMEDOUT)
r = false; r = false;
Mutex.locked = locked; Mutex.locked = locked;
Mutex.lockingPid = getpid(); Mutex.lockingTid = pthread_self();
} }
} }
return r; return r;
@ -83,7 +83,7 @@ void cCondVar::Signal(void)
cMutex::cMutex(void) cMutex::cMutex(void)
{ {
lockingPid = 0; lockingTid = 0;
locked = 0; locked = 0;
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
} }
@ -95,9 +95,9 @@ cMutex::~cMutex()
void cMutex::Lock(void) void cMutex::Lock(void)
{ {
if (getpid() != lockingPid || !locked) { if (!pthread_equal(lockingTid, pthread_self()) || !locked) {
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
lockingPid = getpid(); lockingTid = pthread_self();
} }
locked++; locked++;
} }
@ -105,7 +105,7 @@ void cMutex::Lock(void)
void cMutex::Unlock(void) void cMutex::Unlock(void)
{ {
if (!--locked) { if (!--locked) {
lockingPid = 0; lockingTid = 0;
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
} }
} }
@ -125,7 +125,7 @@ cThread::cThread(void)
signalHandlerInstalled = true; signalHandlerInstalled = true;
} }
running = false; running = false;
parentPid = threadPid = 0; parentTid = childTid = 0;
} }
cThread::~cThread() cThread::~cThread()
@ -139,8 +139,9 @@ void cThread::SignalHandler(int signum)
void *cThread::StartThread(cThread *Thread) void *cThread::StartThread(cThread *Thread)
{ {
Thread->threadPid = getpid(); Thread->childTid = pthread_self();
Thread->Action(); Thread->Action();
Thread->childTid = 0;
return NULL; return NULL;
} }
@ -148,9 +149,9 @@ bool cThread::Start(void)
{ {
if (!running) { if (!running) {
running = true; running = true;
parentPid = getpid(); parentTid = pthread_self();
pthread_create(&thread, NULL, (void *(*) (void *))&StartThread, (void *)this); pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this);
pthread_setschedparam(thread, SCHED_RR, 0); pthread_setschedparam(childTid, SCHED_RR, 0);
usleep(10000); // otherwise calling Active() immediately after Start() causes a "pure virtual method called" error usleep(10000); // otherwise calling Active() immediately after Start() causes a "pure virtual method called" error
} }
return true; //XXX return value of pthread_create()??? return true; //XXX return value of pthread_create()???
@ -158,12 +159,21 @@ bool cThread::Start(void)
bool cThread::Active(void) bool cThread::Active(void)
{ {
if (threadPid) { if (childTid) {
if (kill(threadPid, SIGIO) < 0) { // couldn't find another way of checking whether the thread is still running - any ideas? //
if (errno == ESRCH) // Single UNIX Spec v2 says:
threadPid = 0; //
else // 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; LOG_ERROR;
childTid = 0;
} }
else else
return true; return true;
@ -180,14 +190,14 @@ void cThread::Cancel(int WaitSeconds)
return; return;
usleep(10000); 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) 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) bool cThread::EmergencyExit(bool Request)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __THREAD_H
@ -32,7 +32,7 @@ class cMutex {
friend class cCondVar; friend class cCondVar;
private: private:
pthread_mutex_t mutex; pthread_mutex_t mutex;
pid_t lockingPid; pthread_t lockingTid;
int locked; int locked;
public: public:
cMutex(void); cMutex(void);
@ -44,9 +44,8 @@ public:
class cThread { class cThread {
friend class cThreadLock; friend class cThreadLock;
private: private:
pthread_t thread; pthread_t parentTid, childTid;
cMutex mutex; cMutex mutex;
pid_t parentPid, threadPid;
bool running; bool running;
static bool emergencyExitRequested; static bool emergencyExitRequested;
static bool signalHandlerInstalled; static bool signalHandlerInstalled;