[mythtv] Freezes on 64bit when starting recordings or LiveTV

Jonas Meurer jonas at freesources.org
Sat Apr 2 09:40:14 UTC 2005


On 01/04/2005 Greg Turnquist wrote:
> Jonas,
> 
> I tried applying your patch to my Debian64 system. It didn't apply and instead 
> gave me this....
> 
> mythtv at stargate:~/src/mythtv$ patch -p1 < patch.txt
> can't find file to patch at input line 4
> Perhaps you used the wrong -p or --strip option?
> The text leading up to this was:
> --------------------------
> |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
> --------------------------
> File to patch:
> 
> I typed in the filename, but it still blew up on me...
> File to patch: libs/libmythtv/RingBuffer.cpp
> patching file libs/libmythtv/RingBuffer.cpp
> patch: **** malformed patch at line 5:      numfailures = 0;
> 
> mythtv at stargate:~/src/mythtv$
> 
> Is this patch in proper CVS format, or am I using patch incorrectly?

I guess that you use the patch incorrectly. It works for both 0.17
upstream sources and 0.17 debian source (from mdz):

jonas at resivo:~/debian/mythtv/mythtv-0.17$ patch -p1 < ../mythtv-0.17-amd64.patch
patching file libs/libmythtv/RingBuffer.cpp
patching file libs/libmythtv/RingBuffer.h
jonas at resivo:~/debian/mythtv/mythtv-0.17$

as you can see, the patch applies well for me at mdz's debian mythtv
0.17 sources.

i've attached the patch again, to go sure that you have the right patch
for MythTV release 0.17.

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