diff options
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 59 |
1 files changed, 50 insertions, 9 deletions
@@ -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 ------------------------------------------------------------- |