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 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

View File

@ -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
View File

@ -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:
----------------------------------

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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)

View File

@ -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;