use read/write lock for eCueSheet
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 14 Jun 2007 12:46:29 +0000 (12:46 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 14 Jun 2007 12:46:29 +0000 (12:46 +0000)
lib/base/elock.h
lib/dvb/dvb.cpp
lib/dvb/idvb.h

index 7bf25eba3e71482801d1b279608ee69157a3f83c..51582e67fe5a3d6e97ba97c82856c4bcd3127019 100644 (file)
@@ -18,6 +18,65 @@ public:
        }
 };
 
+class eRdWrLock
+{
+       friend class eRdLocker;
+       friend class eWrLocker;
+       pthread_rwlock_t m_lock;
+       eRdWrLock(eRdWrLock &);
+public:
+       eRdWrLock()
+       {
+               pthread_rwlock_init(&m_lock, 0);
+       }
+       ~eRdWrLock()
+       {
+               pthread_rwlock_destroy(&m_lock);
+       }
+       void RdLock()
+       {
+               pthread_rwlock_rdlock(&m_lock);
+       }
+       void WrLock()
+       {
+               pthread_rwlock_wrlock(&m_lock);
+       }
+       void Unlock()
+       {
+               pthread_rwlock_unlock(&m_lock);
+       }
+};
+
+class eRdLocker
+{
+       eRdWrLock &m_lock;
+public:
+       eRdLocker(eRdWrLock &m)
+               : m_lock(m)
+       {
+               pthread_rwlock_rdlock(&m_lock.m_lock);
+       }
+       ~eRdLocker()
+       {
+               pthread_rwlock_unlock(&m_lock.m_lock);
+       }
+};
+
+class eWrLocker
+{
+       eRdWrLock &m_lock;
+public:
+       eWrLocker(eRdWrLock &m)
+               : m_lock(m)
+       {
+               pthread_rwlock_wrlock(&m_lock.m_lock);
+       }
+       ~eWrLocker()
+       {
+               pthread_rwlock_unlock(&m_lock.m_lock);
+       }
+};
+
 class eSingleLock
 {
        friend class eSingleLocker;
index 0184347bc26bebc30dd9f6914ad7e76ca41a8917..6e87585e9fe58dbdfc3ffe7f8e866ed23dc941df 100644 (file)
@@ -891,8 +891,10 @@ void eDVBChannel::cueSheetEvent(int event)
        case eCueSheet::evtSkipmode:
        {
                {
-                       eSingleLocker l(m_cue->m_lock);
+                       m_cue->m_lock.WrLock();
                        m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
+                       m_cue->m_lock.Unlock();
+                       eRdLocker l(m_cue->m_lock);
                        if (m_cue->m_skipmode_ratio)
                        {
                                int bitrate = m_tstools.calcBitrate(); /* in bits/s */
@@ -975,13 +977,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                return;
        }
 
-       eSingleLocker l(m_cue->m_lock);
-       
+       m_cue->m_lock.RdLock();
        if (!m_cue->m_decoding_demux)
        {
                start = current_offset;
                size = max;
                eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
+               m_cue->m_lock.Unlock();
                return;
        }
 
@@ -998,7 +1000,11 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
        while (!m_cue->m_seek_requests.empty())
        {
                std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
+               m_cue->m_lock.Unlock();
+               m_cue->m_lock.WrLock();
                m_cue->m_seek_requests.pop_front();
+               m_cue->m_lock.Unlock();
+               m_cue->m_lock.RdLock();
                int relative = seek.first;
                pts_t pts = seek.second;
 
@@ -1071,6 +1077,8 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
        }
 
+       m_cue->m_lock.Unlock();
+
        for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
        {
                long long aligned_start = align(i->first, blocksize);
@@ -1404,25 +1412,24 @@ eCueSheet::eCueSheet()
 
 void eCueSheet::seekTo(int relative, const pts_t &pts)
 {
-       {
-               eSingleLocker l(m_lock);
-               m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
-       }
+       m_lock.WrLock();
+       m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
+       m_lock.Unlock();
        m_event(evtSeek);
 }
        
 void eCueSheet::clear()
 {
-       eSingleLocker l(m_lock);
+       m_lock.WrLock();
        m_spans.clear();
+       m_lock.Unlock();
 }
 
 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
 {
-       {
-               eSingleLocker l(m_lock);
-               m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
-       }
+       m_lock.WrLock();
+       m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
+       m_lock.Unlock();
 }
 
 void eCueSheet::commitSpans()
@@ -1432,10 +1439,9 @@ void eCueSheet::commitSpans()
 
 void eCueSheet::setSkipmode(const pts_t &ratio)
 {
-       {
-               eSingleLocker l(m_lock);
-               m_skipmode_ratio = ratio;
-       }
+       m_lock.WrLock();
+       m_skipmode_ratio = ratio;
+       m_lock.Unlock();
        m_event(evtSkipmode);
 }
 
index 9c210502c2007d774a02767b44eb16631fe7a984..14d6ebb0e4de361362fabbb13dc66c609c68eef2 100644 (file)
@@ -564,7 +564,7 @@ public:
        void setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder);
        
                        /* frontend and backend */
-       eSingleLock m_lock;
+       eRdWrLock m_lock;
        
                        /* backend */
        enum { evtSeek, evtSkipmode, evtSpanChanged };