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.
|
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.
|
||||||
|
73
recording.c
73
recording.c
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user