diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2018-03-04 11:31:21 +0100 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2018-03-04 11:31:21 +0100 |
commit | 75648e80cfb13ee0589b246c4c0238b5e7c99abd (patch) | |
tree | 2e0019867d7bf6ef7052ec680a775af16f365dd5 | |
parent | 8a7540321d01a11f461b99fc313e463ba58a5f65 (diff) | |
download | vdr-75648e80cfb13ee0589b246c4c0238b5e7c99abd.tar.gz vdr-75648e80cfb13ee0589b246c4c0238b5e7c99abd.tar.bz2 |
Modified cStateLock's SetExplicitModify() and IncState()
-rw-r--r-- | HISTORY | 4 | ||||
-rw-r--r-- | thread.c | 59 | ||||
-rw-r--r-- | thread.h | 22 | ||||
-rw-r--r-- | tools.c | 4 |
4 files changed, 71 insertions, 18 deletions
@@ -9162,7 +9162,7 @@ Video Disk Recorder Revision History a subdirectory. - SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details). -2018-03-03: Version 2.3.9 +2018-03-04: Version 2.3.9 - Updated the Italian OSD texts (thanks to Diego Pierotto). - Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). @@ -9293,3 +9293,5 @@ Video Disk Recorder Revision History stuttering replay in fast forward and fast rewind mode in case the video directory is mounted via NFS. You can re-enable it by setting the macro USE_FADVISE_READ to 1 in tools.c. +- Modified cStateLock's SetExplicitModify() and IncState() (changed to SetModified()) to + allow for the introduction of syncing a separate cStateKey to a cStateLock. @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 4.11 2017/06/25 12:08:16 kls Exp $ + * $Id: thread.c 4.12 2018/03/04 11:23:09 kls Exp $ */ #include "thread.h" @@ -716,7 +716,8 @@ cStateLock::cStateLock(const char *Name) name = Name; threadId = 0; state = 0; - explicitModify = false; + explicitModify = emDisabled; + syncStateKey = NULL; } bool cStateLock::Lock(cStateKey &StateKey, bool Write, int TimeoutMs) @@ -764,30 +765,70 @@ void cStateLock::Unlock(cStateKey &StateKey, bool IncState) return; } if (StateKey.write && threadId != cThread::ThreadId()) { - esyslog("ERROR: cStateLock::Unlock() called without holding a lock (tid=%d, lock=%s)", threadId, name); + esyslog("ERROR: cStateLock::Unlock() called without holding a write lock (tid=%d, lock=%s)", threadId, name); ABORT; return; } - if (StateKey.write && IncState && !explicitModify) + if (StateKey.write && (IncState && explicitModify != emArmed || explicitModify == emEnabled)) { + if (syncStateKey && syncStateKey->state == state) + syncStateKey->state++; state++; + } StateKey.state = state; if (StateKey.write) { StateKey.write = false; threadId = 0; - explicitModify = false; + explicitModify = emDisabled; + syncStateKey = NULL; } dbglockseq(name, false, false); rwLock.Unlock(); } -void cStateLock::IncState(void) +void cStateLock::SetSyncStateKey(cStateKey &StateKey) { + dbglocking("%5d %-12s %10p SetSyncStateKey\n", cThread::ThreadId(), name, &StateKey); if (threadId != cThread::ThreadId()) { - esyslog("ERROR: cStateLock::IncState() called without holding a lock (tid=%d, lock=%s)", threadId, name); + esyslog("ERROR: cStateLock::SetSyncStateKey() called without holding a write lock (tid=%d, lock=%s)", threadId, name); ABORT; + return; } - else - state++; + if (StateKey.stateLock == this) { + esyslog("ERROR: cStateLock::SetSyncStateKey() called with locked key (tid=%d, lock=%s)", threadId, name); + ABORT; + return; + } + if (syncStateKey) { + esyslog("ERROR: cStateLock::SetSyncStateKey() called twice (tid=%d, lock=%s)", threadId, name); + ABORT; + return; + } + syncStateKey = &StateKey; +} + +void cStateLock::SetExplicitModify(void) +{ + if (threadId != cThread::ThreadId()) { + esyslog("ERROR: cStateLock::SetExplicitModify() called without holding a write lock (tid=%d, lock=%s)", threadId, name); + ABORT; + return; + } + if (explicitModify != emDisabled) { + esyslog("ERROR: cStateLock::SetExplicitModify() called twice (tid=%d, lock=%s)", threadId, name); + ABORT; + return; + } + explicitModify = emArmed; +} + +void cStateLock::SetModified(void) +{ + if (threadId != cThread::ThreadId()) { + esyslog("ERROR: cStateLock::SetModified() called without holding a write lock (tid=%d, lock=%s)", threadId, name); + ABORT; + return; + } + explicitModify = emEnabled; } // --- cStateKey ------------------------------------------------------------- @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.h 4.3 2017/06/03 12:43:22 kls Exp $ + * $Id: thread.h 4.4 2018/03/04 11:27:55 kls Exp $ */ #ifndef __THREAD_H @@ -171,11 +171,13 @@ class cStateKey; class cStateLock { friend class cStateKey; private: + enum { emDisabled = 0, emArmed, emEnabled }; const char *name; tThreadId threadId; cRwLock rwLock; int state; - bool explicitModify; + int explicitModify; + cStateKey *syncStateKey; void Unlock(cStateKey &StateKey, bool IncState = true); ///< Releases a lock that has been obtained by a previous call to Lock() ///< with the given StateKey. If this was a write-lock, and IncState is true, @@ -211,13 +213,21 @@ public: ///< If Write is true (i.e. a write-lock is requested), the states of the ///< lock and the given StateKey don't matter, it will always try to obtain ///< a write lock. - void SetExplicitModify(void) { explicitModify = true; } + void SetSyncStateKey(cStateKey &StateKey); + ///< Sets the given StateKey to be synchronized to the state of this lock. + ///< The caller must currenty hold a write lock on this lock, with a cStateKey + ///< that is different from the given StateKey. If, when removing the key that + ///< is holding the write lock, the StateKey's current state is the same as that + ///< of the lock, it will be increased together with the lock's state. + void SetExplicitModify(void); ///< If you have obtained a write lock on this lock, and you don't want its ///< state to be automatically incremented when the lock is released, a call to - ///< this function will disable this, and you can explicitly call IncState() + ///< this function will disable this, and you can explicitly call SetModified() ///< to increment the state. - void IncState(void); - ///< Increments the state of this lock. + void SetModified(void); + ///< Sets this lock to have its state incremented when the current write lock + ///< state key is removed. Must have called SetExplicitModify() before calling + ///< this function. }; class cStateKey { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 4.10 2018/03/03 19:35:31 kls Exp $ + * $Id: tools.c 4.11 2018/03/04 10:28:04 kls Exp $ */ #include "tools.h" @@ -2253,7 +2253,7 @@ void cListBase::SetExplicitModify(void) void cListBase::SetModified(void) { - stateLock.IncState(); + stateLock.SetModified(); } const cListObject *cListBase::Get(int Index) const |