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:
parent
ea217de338
commit
7455fbd2ad
3
HISTORY
3
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).
|
||||
|
||||
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 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
|
||||
that have not yet been moved completely as non-selectable. This avoids situations
|
||||
where trying to play such a recording might fail.
|
||||
- Fixed canceling moving a folder with several recordings between volumes.
|
||||
|
73
recording.c
73
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 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"
|
||||
@ -1682,7 +1682,6 @@ private:
|
||||
public:
|
||||
cDirCopier(const char *DirNameSrc, const char *DirNameDst);
|
||||
virtual ~cDirCopier();
|
||||
void Stop(void);
|
||||
bool Error(void) { return error; }
|
||||
};
|
||||
|
||||
@ -1697,7 +1696,7 @@ cDirCopier::cDirCopier(const char *DirNameSrc, const char *DirNameDst)
|
||||
|
||||
cDirCopier::~cDirCopier()
|
||||
{
|
||||
Stop();
|
||||
Cancel(3);
|
||||
}
|
||||
|
||||
bool cDirCopier::Throttled(void)
|
||||
@ -1833,17 +1832,6 @@ void cDirCopier::Action(void)
|
||||
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 -----------------------------------------------
|
||||
|
||||
class cRecordingsHandlerEntry : public cListObject {
|
||||
@ -1853,14 +1841,18 @@ private:
|
||||
cString fileNameDst;
|
||||
cCutter *cutter;
|
||||
cDirCopier *copier;
|
||||
bool error;
|
||||
void ClearPending(void) { usage &= ~ruPending; }
|
||||
public:
|
||||
cRecordingsHandlerEntry(int Usage, const char *FileNameSrc, const char *FileNameDst);
|
||||
~cRecordingsHandlerEntry();
|
||||
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 *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)
|
||||
@ -1870,6 +1862,7 @@ cRecordingsHandlerEntry::cRecordingsHandlerEntry(int Usage, const char *FileName
|
||||
fileNameDst = FileNameDst;
|
||||
cutter = NULL;
|
||||
copier = NULL;
|
||||
error = false;
|
||||
}
|
||||
|
||||
cRecordingsHandlerEntry::~cRecordingsHandlerEntry()
|
||||
@ -1890,22 +1883,22 @@ int cRecordingsHandlerEntry::Usage(const char *FileName) const
|
||||
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:
|
||||
if (cutter) {
|
||||
if (cutter->Active())
|
||||
return true;
|
||||
Error |= cutter->Error();
|
||||
error = cutter->Error();
|
||||
delete cutter;
|
||||
cutter = NULL;
|
||||
}
|
||||
else if (copier) {
|
||||
if (copier->Active())
|
||||
return true;
|
||||
Error |= copier->Error();
|
||||
CopierFinishedOk = !copier->Error();
|
||||
error = copier->Error();
|
||||
delete copier;
|
||||
copier = NULL;
|
||||
}
|
||||
@ -1923,19 +1916,34 @@ bool cRecordingsHandlerEntry::Active(cRecordings *Recordings, bool &Error)
|
||||
Recordings->SetModified(); // to trigger a state change
|
||||
return true;
|
||||
}
|
||||
// Clean up:
|
||||
if (CopierFinishedOk && (Usage() & ruMove) != 0) {
|
||||
// We're done:
|
||||
if (!error && (usage & ruMove) != 0) {
|
||||
cRecording Recording(FileNameSrc());
|
||||
if (Recording.Delete()) {
|
||||
if (Recording.Delete())
|
||||
Recordings->DelByName(Recording.FileName());
|
||||
Recordings->SetModified(); // to trigger a state change
|
||||
}
|
||||
}
|
||||
Recordings->SetModified(); // to trigger a state change
|
||||
Recordings->TouchUpdate();
|
||||
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 RecordingsHandler;
|
||||
@ -1961,8 +1969,11 @@ void cRecordingsHandler::Action(void)
|
||||
Recordings->SetExplicitModify();
|
||||
cMutexLock MutexLock(&mutex);
|
||||
if (cRecordingsHandlerEntry *r = operations.First()) {
|
||||
if (!r->Active(Recordings, error))
|
||||
if (!r->Active(Recordings)) {
|
||||
error |= r->Error();
|
||||
r->Cleanup(Recordings);
|
||||
operations.Del(r);
|
||||
}
|
||||
else
|
||||
Sleep = true;
|
||||
}
|
||||
@ -1978,6 +1989,8 @@ cRecordingsHandlerEntry *cRecordingsHandler::Get(const char *FileName)
|
||||
{
|
||||
if (FileName && *FileName) {
|
||||
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)
|
||||
return r;
|
||||
}
|
||||
@ -2020,16 +2033,14 @@ void cRecordingsHandler::Del(const char *FileName)
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
if (cRecordingsHandlerEntry *r = Get(FileName))
|
||||
operations.Del(r);
|
||||
r->SetCanceled();
|
||||
}
|
||||
|
||||
void cRecordingsHandler::DelAll(void)
|
||||
{
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
operations.Clear();
|
||||
}
|
||||
Cancel(3);
|
||||
for (cRecordingsHandlerEntry *r = operations.First(); r; r = operations.Next(r))
|
||||
r->SetCanceled();
|
||||
}
|
||||
|
||||
int cRecordingsHandler::GetUsage(const char *FileName)
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* 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
|
||||
@ -38,6 +38,7 @@ enum eRecordingUsage {
|
||||
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
|
||||
ruCanceled = 0x8000, // the operation has been canceled, waiting for cleanup
|
||||
};
|
||||
|
||||
void RemoveDeletedRecordings(void);
|
||||
|
Loading…
Reference in New Issue
Block a user