Modified cStateLock's SetExplicitModify() and IncState()

This commit is contained in:
Klaus Schmidinger 2018-03-04 11:31:21 +01:00
parent 8a7540321d
commit 75648e80cf
4 changed files with 71 additions and 18 deletions

View File

@ -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.

View File

@ -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::SetSyncStateKey() called without holding a write lock (tid=%d, lock=%s)", threadId, name);
ABORT;
return;
}
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::IncState() called without holding a lock (tid=%d, lock=%s)", threadId, name);
esyslog("ERROR: cStateLock::SetExplicitModify() called without holding a write lock (tid=%d, lock=%s)", threadId, name);
ABORT;
return;
}
else
state++;
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 -------------------------------------------------------------

View File

@ -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 {

View File

@ -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