From 18e7903b78f856d9959257bc88b307b80c460681 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 7 Feb 2015 14:29:14 +0100 Subject: Fixed a deadlock in accessing marks --- menu.c | 14 +++++++------- recording.h | 17 ++++++----------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/menu.c b/menu.c index fd18c1bb..6f942437 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 3.43 2015/02/06 15:20:11 kls Exp $ + * $Id: menu.c 3.44 2015/02/07 14:14:50 kls Exp $ */ #include "menu.h" @@ -5390,11 +5390,15 @@ void cReplayControl::MarkToggle(void) int Current, Total; if (GetIndex(Current, Total, true)) { lastCurrent = -1; // triggers redisplay - cMutexLock MutexLock(&marks); - if (cMark *m = marks.Get(Current)) + if (cMark *m = marks.Get(Current)) { + marks.Lock(); marks.Del(m); + marks.Unlock(); + } else { + marks.Lock(); marks.Add(Current); + marks.Unlock(); bool Play, Forward; int Speed; if (Setup.PauseOnMarkSet || GetReplayMode(Play, Forward, Speed) && !Play) { @@ -5411,7 +5415,6 @@ void cReplayControl::MarkJump(bool Forward) { int Current, Total; if (GetIndex(Current, Total)) { - cMutexLock MutexLock(&marks); if (marks.Count()) { if (cMark *m = Forward ? marks.GetNext(Current) : marks.GetPrev(Current)) { if (!Setup.PauseOnMarkJump) { @@ -5440,7 +5443,6 @@ void cReplayControl::MarkMove(int Frames, bool MarkRequired) bool Play, Forward; int Speed; GetReplayMode(Play, Forward, Speed); - cMutexLock MutexLock(&marks); cMark *m = marks.Get(Current); if (!Play && m) { displayFrames = true; @@ -5476,7 +5478,6 @@ void cReplayControl::EditCut(void) if (*fileName) { Hide(); if (!RecordingsHandler.GetUsage(fileName)) { - cMutexLock MutexLock(&marks); if (!marks.Count()) Skins.Message(mtError, tr("No editing marks defined!")); else if (!marks.GetNumSequences()) @@ -5498,7 +5499,6 @@ void cReplayControl::EditTest(void) { int Current, Total; if (GetIndex(Current, Total)) { - cMutexLock MutexLock(&marks); cMark *m = marks.Get(Current); if (!m) m = marks.GetNext(Current); diff --git a/recording.h b/recording.h index f6eaa19b..876e0b25 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 3.7 2015/02/06 15:17:04 kls Exp $ + * $Id: recording.h 3.8 2015/02/07 14:29:14 kls Exp $ */ #ifndef __RECORDING_H @@ -369,26 +369,21 @@ public: void Align(void); void Sort(void); void Add(int Position); + ///< If this cMarks object is used by multiple threads, the caller must Lock() + ///< it before calling Add() and Unlock() it afterwards. The same applies to + ///< calls to Del(), or any of the functions that return a "cMark *", in case + ///< an other thread might modifiy the list while the returned pointer is + ///< considered valid. cMark *Get(int Position); - ///< If this cMarks object is used by multiple threads, the caller must hold a lock - ///< on this object as long as it handles the returned pointer. cMark *GetPrev(int Position); - ///< If this cMarks object is used by multiple threads, the caller must hold a lock - ///< on this object as long as it handles the returned pointer. cMark *GetNext(int Position); - ///< If this cMarks object is used by multiple threads, the caller must hold a lock - ///< on this object as long as it handles the returned pointer. cMark *GetNextBegin(cMark *EndMark = NULL); ///< Returns the next "begin" mark after EndMark, skipping any marks at the ///< same position as EndMark. If EndMark is NULL, the first actual "begin" ///< will be returned (if any). - ///< If this cMarks object is used by multiple threads, the caller must hold a lock - ///< on this object as long as it handles the returned pointer. cMark *GetNextEnd(cMark *BeginMark); ///< Returns the next "end" mark after BeginMark, skipping any marks at the ///< same position as BeginMark. - ///< If this cMarks object is used by multiple threads, the caller must hold a lock - ///< on this object as long as it handles the returned pointer. int GetNumSequences(void); ///< Returns the actual number of sequences to be cut from the recording. ///< If there is only one actual "begin" mark, and it is positioned at index -- cgit v1.2.3