diff --git a/HISTORY b/HISTORY index 143c2f45..469f6016 100644 --- a/HISTORY +++ b/HISTORY @@ -786,3 +786,8 @@ Video Disk Recorder Revision History at the expected time). - Made the volume, mute and power keys work when a menu is active, too (thanks to Matthias Weingart). + +2001-09-30: Version 0.97 + +- Implemented a lock file to prevent more than one instance of VDR from removing + files from the video directory at the same time. diff --git a/config.h b/config.h index 8012cd26..081e3374 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.81 2001/09/22 13:37:05 kls Exp $ + * $Id: config.h 1.82 2001/09/30 10:37:18 kls Exp $ */ #ifndef __CONFIG_H @@ -19,7 +19,7 @@ #include "eit.h" #include "tools.h" -#define VDRVERSION "0.96" +#define VDRVERSION "0.97" #define MAXPRIORITY 99 #define MAXLIFETIME 99 diff --git a/recording.c b/recording.c index df504074..11fb851e 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 1.37 2001/09/23 13:43:29 kls Exp $ + * $Id: recording.c 1.38 2001/09/30 10:29:11 kls Exp $ */ #define _GNU_SOURCE @@ -45,6 +45,10 @@ void RemoveDeletedRecordings(void) { static time_t LastRemoveCheck = 0; if (time(NULL) - LastRemoveCheck > REMOVECHECKDELTA) { + // Make sure only one instance of VDR does this: + cLockFile LockFile(VideoDirectory); + if (!LockFile.Lock()) + return; // Remove the oldest file that has been "deleted": cRecordings Recordings; if (Recordings.Load(true)) { @@ -74,6 +78,10 @@ void AssertFreeDiskSpace(int Priority) static time_t LastFreeDiskCheck = 0; if (time(NULL) - LastFreeDiskCheck > DISKCHECKDELTA) { if (!VideoFileSpaceAvailable(MINDISKSPACE)) { + // Make sure only one instance of VDR does this: + cLockFile LockFile(VideoDirectory); + if (!LockFile.Lock()) + return; // Remove the oldest file that has been "deleted": cRecordings Recordings; if (Recordings.Load(true)) { diff --git a/tools.c b/tools.c index 7238137e..57188022 100644 --- a/tools.c +++ b/tools.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.46 2001/09/22 12:13:40 kls Exp $ + * $Id: tools.c 1.47 2001/09/30 10:36:40 kls Exp $ */ #define _GNU_SOURCE @@ -590,6 +590,72 @@ bool cSafeFile::Close(void) return result; } +// --- cLockFile ------------------------------------------------------------- + +#define LOCKFILENAME ".lock-vdr" +#define LOCKFILESTALETIME 600 // seconds before considering a lock file "stale" + +cLockFile::cLockFile(const char *Directory) +{ + fileName = NULL; + f = -1; + if (DirectoryOk(Directory)) + asprintf(&fileName, "%s/%s", Directory, LOCKFILENAME); +} + +cLockFile::~cLockFile() +{ + Unlock(); + delete fileName; +} + +bool cLockFile::Lock(int WaitSeconds) +{ + if (f < 0 && fileName) { + time_t Timeout = time(NULL) + WaitSeconds; + do { + f = open(fileName, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (f < 0) { + if (errno == EEXIST) { + struct stat fs; + if (stat(fileName, &fs) == 0) { + if (time(NULL) - fs.st_mtime > LOCKFILESTALETIME) { + esyslog(LOG_ERR, "ERROR: removing stale lock file '%s'", fileName); + if (remove(fileName) < 0) { + LOG_ERROR_STR(fileName); + break; + } + continue; + } + } + else if (errno != ENOENT) { + LOG_ERROR_STR(fileName); + break; + } + } + else { + LOG_ERROR_STR(fileName); + break; + } + if (WaitSeconds) + sleep(1); + } + } while (f < 0 && time(NULL) < Timeout); + } + return f >= 0; +} + +void cLockFile::Unlock(void) +{ + if (f >= 0) { + close(f); + remove(fileName); + f = -1; + } + else + esyslog(LOG_ERR, "ERROR: attempt to unlock %s without holding a lock!", fileName); +} + // --- cListObject ----------------------------------------------------------- cListObject::cListObject(void) diff --git a/tools.h b/tools.h index cc67a806..843cbf1d 100644 --- a/tools.h +++ b/tools.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.35 2001/09/22 12:12:55 kls Exp $ + * $Id: tools.h 1.36 2001/09/30 10:20:59 kls Exp $ */ #ifndef __TOOLS_H @@ -97,6 +97,17 @@ public: bool Close(void); }; +class cLockFile { +private: + char *fileName; + int f; +public: + cLockFile(const char *Directory); + ~cLockFile(); + bool Lock(int WaitSeconds = 0); + void Unlock(void); + }; + class cListObject { private: cListObject *prev, *next;