1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed canceling moving a folder with several recordings between volumes

This commit is contained in:
Klaus Schmidinger 2017-12-11 13:55:38 +01:00
parent ea217de338
commit 7455fbd2ad
3 changed files with 47 additions and 34 deletions

View File

@ -9162,7 +9162,7 @@ Video Disk Recorder Revision History
a subdirectory. a subdirectory.
- SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details). - SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details).
2017-12-10: Version 2.3.9 2017-12-11: Version 2.3.9
- Updated the Italian OSD texts (thanks to Diego Pierotto). - Updated the Italian OSD texts (thanks to Diego Pierotto).
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). - Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
@ -9229,3 +9229,4 @@ Video Disk Recorder Revision History
- When moving recordings between volumes, the "Recordings" menu now displays those items - When moving recordings between volumes, the "Recordings" menu now displays those items
that have not yet been moved completely as non-selectable. This avoids situations that have not yet been moved completely as non-selectable. This avoids situations
where trying to play such a recording might fail. where trying to play such a recording might fail.
- Fixed canceling moving a folder with several recordings between volumes.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.c 4.13 2017/12/09 14:24:35 kls Exp $ * $Id: recording.c 4.14 2017/12/11 13:35:14 kls Exp $
*/ */
#include "recording.h" #include "recording.h"
@ -1682,7 +1682,6 @@ private:
public: public:
cDirCopier(const char *DirNameSrc, const char *DirNameDst); cDirCopier(const char *DirNameSrc, const char *DirNameDst);
virtual ~cDirCopier(); virtual ~cDirCopier();
void Stop(void);
bool Error(void) { return error; } bool Error(void) { return error; }
}; };
@ -1697,7 +1696,7 @@ cDirCopier::cDirCopier(const char *DirNameSrc, const char *DirNameDst)
cDirCopier::~cDirCopier() cDirCopier::~cDirCopier()
{ {
Stop(); Cancel(3);
} }
bool cDirCopier::Throttled(void) bool cDirCopier::Throttled(void)
@ -1833,17 +1832,6 @@ void cDirCopier::Action(void)
esyslog("ERROR: can't access '%s'", *dirNameDst); esyslog("ERROR: can't access '%s'", *dirNameDst);
} }
void cDirCopier::Stop(void)
{
Cancel(3);
if (error) {
cVideoDirectory::RemoveVideoFile(dirNameDst);
LOCK_RECORDINGS_WRITE;
Recordings->AddByName(dirNameSrc);
Recordings->DelByName(dirNameDst);
}
}
// --- cRecordingsHandlerEntry ----------------------------------------------- // --- cRecordingsHandlerEntry -----------------------------------------------
class cRecordingsHandlerEntry : public cListObject { class cRecordingsHandlerEntry : public cListObject {
@ -1853,14 +1841,18 @@ private:
cString fileNameDst; cString fileNameDst;
cCutter *cutter; cCutter *cutter;
cDirCopier *copier; cDirCopier *copier;
bool error;
void ClearPending(void) { usage &= ~ruPending; } void ClearPending(void) { usage &= ~ruPending; }
public: public:
cRecordingsHandlerEntry(int Usage, const char *FileNameSrc, const char *FileNameDst); cRecordingsHandlerEntry(int Usage, const char *FileNameSrc, const char *FileNameDst);
~cRecordingsHandlerEntry(); ~cRecordingsHandlerEntry();
int Usage(const char *FileName = NULL) const; int Usage(const char *FileName = NULL) const;
bool Error(void) const { return error; }
void SetCanceled(void) { usage |= ruCanceled; }
const char *FileNameSrc(void) const { return fileNameSrc; } const char *FileNameSrc(void) const { return fileNameSrc; }
const char *FileNameDst(void) const { return fileNameDst; } const char *FileNameDst(void) const { return fileNameDst; }
bool Active(cRecordings *Recordings, bool &Error); bool Active(cRecordings *Recordings);
void Cleanup(cRecordings *Recordings);
}; };
cRecordingsHandlerEntry::cRecordingsHandlerEntry(int Usage, const char *FileNameSrc, const char *FileNameDst) cRecordingsHandlerEntry::cRecordingsHandlerEntry(int Usage, const char *FileNameSrc, const char *FileNameDst)
@ -1870,6 +1862,7 @@ cRecordingsHandlerEntry::cRecordingsHandlerEntry(int Usage, const char *FileName
fileNameDst = FileNameDst; fileNameDst = FileNameDst;
cutter = NULL; cutter = NULL;
copier = NULL; copier = NULL;
error = false;
} }
cRecordingsHandlerEntry::~cRecordingsHandlerEntry() cRecordingsHandlerEntry::~cRecordingsHandlerEntry()
@ -1890,22 +1883,22 @@ int cRecordingsHandlerEntry::Usage(const char *FileName) const
return u; return u;
} }
bool cRecordingsHandlerEntry::Active(cRecordings *Recordings, bool &Error) bool cRecordingsHandlerEntry::Active(cRecordings *Recordings)
{ {
bool CopierFinishedOk = false; if ((usage & ruCanceled) != 0)
return false;
// First test whether there is an ongoing operation: // First test whether there is an ongoing operation:
if (cutter) { if (cutter) {
if (cutter->Active()) if (cutter->Active())
return true; return true;
Error |= cutter->Error(); error = cutter->Error();
delete cutter; delete cutter;
cutter = NULL; cutter = NULL;
} }
else if (copier) { else if (copier) {
if (copier->Active()) if (copier->Active())
return true; return true;
Error |= copier->Error(); error = copier->Error();
CopierFinishedOk = !copier->Error();
delete copier; delete copier;
copier = NULL; copier = NULL;
} }
@ -1923,19 +1916,34 @@ bool cRecordingsHandlerEntry::Active(cRecordings *Recordings, bool &Error)
Recordings->SetModified(); // to trigger a state change Recordings->SetModified(); // to trigger a state change
return true; return true;
} }
// Clean up: // We're done:
if (CopierFinishedOk && (Usage() & ruMove) != 0) { if (!error && (usage & ruMove) != 0) {
cRecording Recording(FileNameSrc()); cRecording Recording(FileNameSrc());
if (Recording.Delete()) { if (Recording.Delete())
Recordings->DelByName(Recording.FileName()); Recordings->DelByName(Recording.FileName());
Recordings->SetModified(); // to trigger a state change
}
} }
Recordings->SetModified(); // to trigger a state change Recordings->SetModified(); // to trigger a state change
Recordings->TouchUpdate(); Recordings->TouchUpdate();
return false; return false;
} }
void cRecordingsHandlerEntry::Cleanup(cRecordings *Recordings)
{
if ((usage & (ruMove | ruCopy)) // this was a move/copy operation...
&& ((usage & ruPending) // ...which had not yet started...
|| copier // ...or not yet finished...
|| error)) { // ...or finished with error
if (copier) {
delete copier;
copier = NULL;
}
cVideoDirectory::RemoveVideoFile(fileNameDst);
if ((usage & ruMove) != 0)
Recordings->AddByName(fileNameSrc);
Recordings->DelByName(fileNameDst);
}
}
// --- cRecordingsHandler ---------------------------------------------------- // --- cRecordingsHandler ----------------------------------------------------
cRecordingsHandler RecordingsHandler; cRecordingsHandler RecordingsHandler;
@ -1961,8 +1969,11 @@ void cRecordingsHandler::Action(void)
Recordings->SetExplicitModify(); Recordings->SetExplicitModify();
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
if (cRecordingsHandlerEntry *r = operations.First()) { if (cRecordingsHandlerEntry *r = operations.First()) {
if (!r->Active(Recordings, error)) if (!r->Active(Recordings)) {
error |= r->Error();
r->Cleanup(Recordings);
operations.Del(r); operations.Del(r);
}
else else
Sleep = true; Sleep = true;
} }
@ -1978,6 +1989,8 @@ cRecordingsHandlerEntry *cRecordingsHandler::Get(const char *FileName)
{ {
if (FileName && *FileName) { if (FileName && *FileName) {
for (cRecordingsHandlerEntry *r = operations.First(); r; r = operations.Next(r)) { for (cRecordingsHandlerEntry *r = operations.First(); r; r = operations.Next(r)) {
if ((r->Usage() & ruCanceled) != 0)
continue;
if (strcmp(FileName, r->FileNameSrc()) == 0 || strcmp(FileName, r->FileNameDst()) == 0) if (strcmp(FileName, r->FileNameSrc()) == 0 || strcmp(FileName, r->FileNameDst()) == 0)
return r; return r;
} }
@ -2020,16 +2033,14 @@ void cRecordingsHandler::Del(const char *FileName)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
if (cRecordingsHandlerEntry *r = Get(FileName)) if (cRecordingsHandlerEntry *r = Get(FileName))
operations.Del(r); r->SetCanceled();
} }
void cRecordingsHandler::DelAll(void) void cRecordingsHandler::DelAll(void)
{ {
{
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
operations.Clear(); for (cRecordingsHandlerEntry *r = operations.First(); r; r = operations.Next(r))
} r->SetCanceled();
Cancel(3);
} }
int cRecordingsHandler::GetUsage(const char *FileName) int cRecordingsHandler::GetUsage(const char *FileName)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.h 4.6 2017/12/09 14:11:16 kls Exp $ * $Id: recording.h 4.7 2017/12/11 12:56:57 kls Exp $
*/ */
#ifndef __RECORDING_H #ifndef __RECORDING_H
@ -38,6 +38,7 @@ enum eRecordingUsage {
ruDst = 0x0040, // the recording is the destination of a cut, move or copy process ruDst = 0x0040, // the recording is the destination of a cut, move or copy process
// //
ruPending = 0x0080, // the recording is pending a cut, move or copy process ruPending = 0x0080, // the recording is pending a cut, move or copy process
ruCanceled = 0x8000, // the operation has been canceled, waiting for cleanup
}; };
void RemoveDeletedRecordings(void); void RemoveDeletedRecordings(void);