summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c59
1 files changed, 50 insertions, 9 deletions
diff --git a/thread.c b/thread.c
index 8fc23400..d2640378 100644
--- a/thread.c
+++ b/thread.c
@@ -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 -------------------------------------------------------------