[mythtv-users] Re: [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-users mailing list