From: Andreas Monzner Date: Thu, 14 Jun 2007 12:46:29 +0000 (+0000) Subject: use read/write lock for eCueSheet X-Git-Tag: 2.6.0~2178 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/be7160f4c15f23e853a3a0ad7b0ad54107ed9ca1 use read/write lock for eCueSheet --- diff --git a/lib/base/elock.h b/lib/base/elock.h index 7bf25eba..51582e67 100644 --- a/lib/base/elock.h +++ b/lib/base/elock.h @@ -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; diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 0184347b..6e87585e 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -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(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 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 >::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(relative, pts)); - } + m_lock.WrLock(); + m_seek_requests.push_back(std::pair(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(begin, end)); - } + m_lock.WrLock(); + m_spans.push_back(std::pair(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); } diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index 9c210502..14d6ebb0 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -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 };