[mythtv] Freezes on 64bit when starting recordings or LiveTV
Jonas Meurer
jonas at freesources.org
Sun Mar 27 16:51:11 UTC 2005
On 27/03/2005 Isaac Richards wrote:
> On Sunday 27 March 2005 05:59 am, Adam Egger wrote:
> > Ok, I've found an old patch from Kyle Rose to replace all
> > pthread_rwlock_* calls with a mix of pthread_mutex_* and
> > pthread_cond_*:
> > http://www.gossamer-threads.com/lists/mythtv/users/107232?search_string=pth
> >read_rwlock;#107232
> >
> > Isaac, is it a bad solution to replace them permanently in RingBuffer.cpp?
>
> Yes. That patch isn't correct, and I'm not going to stop using standard
> functionality just because it's broken on one little-used platform. I'm
> fairly sure people are using native 64-bit stuff elsewhere, so it's just
> seems like Debian's behind as usual.
i upgraded the patch for mythtv 0.17 anyway, as i don't want to wait for
debian/pure64 to fix the glibc.
here it is, for all the people that like to run mythtv 0.17 on
debian/unstable pure64.
bye
jonas
-------------- next part --------------
diff -ru mythtv-0.17.orig/libs/libmythtv/RingBuffer.cpp mythtv-0.17/libs/libmythtv/RingBuffer.cpp
--- mythtv-0.17.orig/libs/libmythtv/RingBuffer.cpp 2005-03-27 14:59:20.000000000 +0200
+++ mythtv-0.17/libs/libmythtv/RingBuffer.cpp 2005-03-27 15:00:11.396760584 +0200
@@ -490,14 +490,17 @@
numfailures = 0;
commserror = false;
- pthread_rwlock_init(&rwlock, NULL);
+ pthread_mutex_init(&hammerlock, NULL);
+ pthread_cond_init(&hammercond, NULL);
+ readers = 0;
+ writers = 0;
}
RingBuffer::~RingBuffer(void)
{
KillReadAheadThread();
- pthread_rwlock_wrlock(&rwlock);
+ unlock();
if (remotefile)
{
delete remotefile;
@@ -525,7 +528,7 @@
void RingBuffer::Reset(void)
{
wantseek = true;
- pthread_rwlock_wrlock(&rwlock);
+ write_lock_wait();
wantseek = false;
if (!normalfile)
@@ -552,7 +555,7 @@
numfailures = 0;
commserror = false;
- pthread_rwlock_unlock(&rwlock);
+ unlock();
}
int RingBuffer::safe_read(int fd, void *data, unsigned sz)
@@ -616,12 +619,43 @@
return ret;
}
+void RingBuffer::read_lock_wait()
+{
+ pthread_mutex_lock(&hammerlock);
+ while (writers > 0)
+ {
+ pthread_cond_wait(&hammercond, &hammerlock);
+ }
+ readers++;
+ pthread_mutex_unlock(&hammerlock);
+}
+
+void RingBuffer::write_lock_wait()
+{
+ pthread_mutex_lock(&hammerlock);
+ while (readers > 0 || writers > 0)
+ {
+ pthread_cond_wait(&hammercond, &hammerlock);
+ }
+ writers = 1;
+ pthread_mutex_unlock(&hammerlock);
+}
+
+void RingBuffer::unlock()
+{
+ pthread_mutex_lock(&hammerlock);
+ if (readers > 0) readers--;
+ else writers = 0;
+ pthread_cond_signal(&hammercond);
+ pthread_mutex_unlock(&hammerlock);
+}
+
#define READ_AHEAD_SIZE (10 * 256000)
void RingBuffer::CalcReadAheadThresh(int estbitrate)
{
wantseek = true;
- pthread_rwlock_wrlock(&rwlock);
+ write_lock_wait();
wantseek = false;
fill_threshold = 0;
@@ -653,7 +687,7 @@
if (fill_min == 0)
fill_min = -1;
- pthread_rwlock_unlock(&rwlock);
+ unlock();
}
int RingBuffer::ReadBufFree(void)
@@ -793,7 +827,7 @@
readaheadpaused = false;
- pthread_rwlock_rdlock(&rwlock);
+ read_lock_wait();
if (totfree > readblocksize && !commserror)
{
// limit the read size
@@ -901,7 +935,7 @@
}
availWaitMutex.unlock();
- pthread_rwlock_unlock(&rwlock);
+ unlock();
if ((used >= fill_threshold || wantseek) && !pausereadthread)
usleep(500);
@@ -1012,7 +1046,7 @@
int RingBuffer::Read(void *buf, int count)
{
- pthread_rwlock_rdlock(&rwlock);
+ read_lock_wait();
int ret = -1;
if (normalfile)
@@ -1068,7 +1102,7 @@
{
if (stopreads)
{
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return 0;
}
@@ -1087,7 +1121,7 @@
if (stopreads)
{
availWaitMutex.unlock();
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return 0;
}
}
@@ -1118,7 +1152,7 @@
}
}
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return ret;
}
@@ -1126,11 +1160,11 @@
{
bool ret = false;
int used, free;
- pthread_rwlock_rdlock(&rwlock);
+ unlock();
if (!tfw)
{
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return ret;
}
@@ -1139,7 +1173,7 @@
ret = (used * 5 > free);
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return ret;
}
@@ -1147,11 +1181,11 @@
{
int ret = -1;
- pthread_rwlock_rdlock(&rwlock);
+ unlock();
if (!tfw)
{
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return ret;
}
@@ -1200,7 +1234,7 @@
availWaitMutex.unlock();
}
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return ret;
}
@@ -1217,7 +1251,7 @@
long long RingBuffer::Seek(long long pos, int whence)
{
wantseek = true;
- pthread_rwlock_wrlock(&rwlock);
+ unlock();
wantseek = false;
long long ret = -1;
@@ -1281,7 +1315,7 @@
if (readaheadrunning)
ResetReadAhead(readpos);
- pthread_rwlock_unlock(&rwlock);
+ unlock();
return ret;
}
diff -ru mythtv-0.17.orig/libs/libmythtv/RingBuffer.h mythtv-0.17/libs/libmythtv/RingBuffer.h
--- mythtv-0.17.orig/libs/libmythtv/RingBuffer.h 2005-03-27 14:59:20.000000000 +0200
+++ mythtv-0.17/libs/libmythtv/RingBuffer.h 2005-03-27 15:00:00.674390632 +0200
@@ -100,7 +100,13 @@
bool stopreads;
- pthread_rwlock_t rwlock;
+ pthread_mutex_t hammerlock;
+ pthread_cond_t hammercond;
+ int readers;
+ int writers;
+ void read_lock_wait();
+ void write_lock_wait();
+ void unlock();
int recorder_num;
RemoteEncoder *remoteencoder;
More information about the mythtv-dev
mailing list