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

Fixed timeout handling in cRwLock::Lock()

This commit is contained in:
Klaus Schmidinger 2005-05-06 14:43:17 +02:00
parent 6ca56047ae
commit 9f7166a891
3 changed files with 28 additions and 23 deletions

View File

@ -765,6 +765,7 @@ Sascha Volkenandt <sascha@akv-soft.de>
for reporting a problem when starting replay of a recording that has no Dolby for reporting a problem when starting replay of a recording that has no Dolby
Digital audio after switching to a channel that has DD and selecting the DD audio Digital audio after switching to a channel that has DD and selecting the DD audio
track track
for reporting a bug in timeout handling in cRwLock::Lock()
Malcolm Caldwell <malcolm.caldwell@ntu.edu.au> Malcolm Caldwell <malcolm.caldwell@ntu.edu.au>
for modifying LOF handling to allow for C-band reception for modifying LOF handling to allow for C-band reception

View File

@ -3496,3 +3496,7 @@ Video Disk Recorder Revision History
actually stored. actually stored.
- Fixed handling lifetime when deciding whether to delete a recording (thanks to - Fixed handling lifetime when deciding whether to delete a recording (thanks to
Udo Richter). Udo Richter).
- Fixed timeout handling in cRwLock::Lock() (thanks to Sascha Volkenandt for reporting
this one).
- Since there are several places in thread.c where a timeout value is calculated,
this has been put into a separate function.

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.41 2005/01/14 13:59:48 kls Exp $ * $Id: thread.c 1.42 2005/05/06 14:39:15 kls Exp $
*/ */
#include "thread.h" #include "thread.h"
@ -17,6 +17,22 @@
#include <unistd.h> #include <unistd.h>
#include "tools.h" #include "tools.h"
static bool GetAbsTime(struct timespec *Abstime, int MillisecondsFromNow)
{
struct timeval now;
if (gettimeofday(&now, NULL) == 0) { // get current time
now.tv_usec += MillisecondsFromNow * 1000; // add the timeout
while (now.tv_usec >= 1000000) { // take care of an overflow
now.tv_sec++;
now.tv_usec -= 1000000;
}
Abstime->tv_sec = now.tv_sec; // seconds
Abstime->tv_nsec = now.tv_usec * 1000; // nano seconds
return true;
}
return false;
}
// --- cCondWait ------------------------------------------------------------- // --- cCondWait -------------------------------------------------------------
cCondWait::cCondWait(void) cCondWait::cCondWait(void)
@ -44,15 +60,8 @@ bool cCondWait::Wait(int TimeoutMs)
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
if (!signaled) { if (!signaled) {
if (TimeoutMs) { if (TimeoutMs) {
struct timeval now; struct timespec abstime;
if (gettimeofday(&now, NULL) == 0) { // get current time if (GetAbsTime(&abstime, TimeoutMs)) {
now.tv_usec += TimeoutMs * 1000; // add the timeout
int sec = now.tv_usec / 1000000;
now.tv_sec += sec;
now.tv_usec -= sec * 1000000;
struct timespec abstime; // build timespec for timedwait
abstime.tv_sec = now.tv_sec; // seconds
abstime.tv_nsec = now.tv_usec * 1000; // nano seconds
while (!signaled) { while (!signaled) {
if (pthread_cond_timedwait(&cond, &mutex, &abstime) == ETIMEDOUT) if (pthread_cond_timedwait(&cond, &mutex, &abstime) == ETIMEDOUT)
break; break;
@ -105,17 +114,8 @@ 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) { if (Mutex.locked) {
struct timeval now; // unfortunately timedwait needs the absolute time, not the delta :-( struct timespec abstime;
if (gettimeofday(&now, NULL) == 0) { // get current time if (GetAbsTime(&abstime, TimeoutMs)) {
now.tv_usec += TimeoutMs * 1000; // add the timeout
while (now.tv_usec >= 1000000) { // take care of an overflow
now.tv_sec++;
now.tv_usec -= 1000000;
}
struct timespec abstime; // build timespec for timedwait
abstime.tv_sec = now.tv_sec; // seconds
abstime.tv_nsec = now.tv_usec * 1000; // nano seconds
int locked = Mutex.locked; int locked = Mutex.locked;
Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_timedwait Mutex.locked = 0; // have to clear the locked count here, as pthread_cond_timedwait
// does an implizit unlock of the mutex. // does an implizit unlock of the mutex.
@ -150,8 +150,8 @@ bool cRwLock::Lock(bool Write, int TimeoutMs)
int Result = 0; int Result = 0;
struct timespec abstime; struct timespec abstime;
if (TimeoutMs) { if (TimeoutMs) {
abstime.tv_sec = TimeoutMs / 1000; if (!GetAbsTime(&abstime, TimeoutMs))
abstime.tv_nsec = (TimeoutMs % 1000) * 1000000; TimeoutMs = 0;
} }
if (Write) if (Write)
Result = TimeoutMs ? pthread_rwlock_timedwrlock(&rwlock, &abstime) : pthread_rwlock_wrlock(&rwlock); Result = TimeoutMs ? pthread_rwlock_timedwrlock(&rwlock, &abstime) : pthread_rwlock_wrlock(&rwlock);