summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2018-03-04 11:31:21 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2018-03-04 11:31:21 +0100
commit75648e80cfb13ee0589b246c4c0238b5e7c99abd (patch)
tree2e0019867d7bf6ef7052ec680a775af16f365dd5
parent8a7540321d01a11f461b99fc313e463ba58a5f65 (diff)
downloadvdr-75648e80cfb13ee0589b246c4c0238b5e7c99abd.tar.gz
vdr-75648e80cfb13ee0589b246c4c0238b5e7c99abd.tar.bz2
Modified cStateLock's SetExplicitModify() and IncState()
-rw-r--r--HISTORY4
-rw-r--r--thread.c59
-rw-r--r--thread.h22
-rw-r--r--tools.c4
4 files changed, 71 insertions, 18 deletions
diff --git a/HISTORY b/HISTORY
index 7a0e034d..869fd049 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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.
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 -------------------------------------------------------------
diff --git a/thread.h b/thread.h
index fe8535b7..790c29a8 100644
--- a/thread.h
+++ b/thread.h
@@ -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 {
diff --git a/tools.c b/tools.c
index 4d3489af..7330fce1 100644
--- a/tools.c
+++ b/tools.c
@@ -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