From 14b907b01cb6f9ecd2b190386924eee454273f29 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Wed, 15 Feb 2023 14:59:25 +0100 Subject: [PATCH] Fixed a possible crash if an editing process is canceled while the edited recording is being replayed (new solution) --- HISTORY | 2 ++ recording.c | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/HISTORY b/HISTORY index 05b148b6..1a786ab0 100644 --- a/HISTORY +++ b/HISTORY @@ -9846,3 +9846,5 @@ Video Disk Recorder Revision History - Reverted 'Fixed a possible crash if an editing process is canceled while the edited recording is being replayed' (introduced in version 2.6.2), because it caused a deadlock when moving recordings between volumes. +- Fixed a possible crash if an editing process is canceled while the edited recording + is being replayed (new solution). diff --git a/recording.c b/recording.c index 4f92423c..c7ffb1ee 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 5.21 2023/02/15 14:01:20 kls Exp $ + * $Id: recording.c 5.22 2023/02/15 14:59:25 kls Exp $ */ #include "recording.h" @@ -312,23 +312,31 @@ bool cResumeFile::Save(int Index) if (safe_write(f, &Index, sizeof(Index)) < 0) LOG_ERROR_STR(fileName); close(f); - LOCK_RECORDINGS_WRITE; - Recordings->ResetResume(fileName); - return true; } + else + return false; } else { FILE *f = fopen(fileName, "w"); if (f) { fprintf(f, "I %d\n", Index); fclose(f); - LOCK_RECORDINGS_WRITE; - Recordings->ResetResume(fileName); } - else + else { LOG_ERROR_STR(fileName); - return true; + return false; + } } + // Not using LOCK_RECORDINGS_WRITE here, because we might already hold a lock in cRecordingsHandler::Action() + // and end up here if an editing process is canceled while the edited recording is being replayed. The worst + // that can happen if we don't get this lock here is that the resume info in the Recordings list is not updated, + // but that doesn't matter because the recording is deleted, anyway. + cStateKey StateKey; + if (cRecordings *Recordings = cRecordings::GetRecordingsWrite(StateKey, 1)) { + Recordings->ResetResume(fileName); + StateKey.Remove(); + } + return true; } return false; }