mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Fixed a possible crash if the recordings list is updated externally while the Recordings menu is open
This commit is contained in:
		| @@ -2864,6 +2864,8 @@ Lars Hanisch <dvb@flensrocker.de> | ||||
|  used | ||||
|  for making the LIRC remote control connect to the socket even if it doesn't yet exist | ||||
|  when VDR is started | ||||
|  for reporting a possible crash if the recordings list is updated externally while the | ||||
|  Recordings menu is open | ||||
|  | ||||
| Alex Lasnier <alex@fepg.org> | ||||
|  for adding tuning support for ATSC devices | ||||
|   | ||||
							
								
								
									
										4
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -8032,7 +8032,7 @@ Video Disk Recorder Revision History | ||||
|   the last replayed recording (if any) by pressing Ok repeatedly in the Recordings | ||||
|   menu. | ||||
|  | ||||
| 2013-11-15: Version 2.1.3 | ||||
| 2013-12-24: Version 2.1.3 | ||||
|  | ||||
| - Changed the return value of cPositioner::HorizonLongitude() to 0 in case the | ||||
|   latitude of the antenna location is beyond +/-81 degrees. | ||||
| @@ -8065,3 +8065,5 @@ Video Disk Recorder Revision History | ||||
|   by Marko M<>kel<65>). | ||||
| - Fixed uninitialized item area coordinates in cSkinLCARSDisplayMenu (reported by | ||||
|   Marko M<>kel<65>). | ||||
| - Fixed a possible crash if the recordings list is updated externally while the | ||||
|   Recordings menu is open (reported by Lars Hanisch). | ||||
|   | ||||
							
								
								
									
										69
									
								
								recording.c
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								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 3.8 2013/10/20 09:51:23 kls Exp $ | ||||
|  * $Id: recording.c 3.9 2013/12/24 14:32:29 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "recording.h" | ||||
| @@ -76,6 +76,7 @@ bool DirectoryEncoding = false; | ||||
| int InstanceId = 0; | ||||
|  | ||||
| cRecordings DeletedRecordings(true); | ||||
| static cRecordings VanishedRecordings; | ||||
|  | ||||
| // --- cRemoveDeletedRecordingsThread ---------------------------------------- | ||||
|  | ||||
| @@ -220,6 +221,14 @@ void AssertFreeDiskSpace(int Priority, bool Force) | ||||
|      } | ||||
| } | ||||
|  | ||||
| // --- Clear vanished recordings --------------------------------------------- | ||||
|  | ||||
| void ClearVanishedRecordings(void) | ||||
| { | ||||
|   cThreadLock RecordingsLock(&Recordings); // yes, it *is* Recordings! | ||||
|   VanishedRecordings.Clear(); | ||||
| } | ||||
|  | ||||
| // --- cResumeFile ----------------------------------------------------------- | ||||
|  | ||||
| cResumeFile::cResumeFile(const char *FileName, bool IsPesRecording) | ||||
| @@ -1346,6 +1355,7 @@ cRecordings::cRecordings(bool Deleted) | ||||
| :cThread("video directory scanner") | ||||
| { | ||||
|   deleted = Deleted; | ||||
|   initial = true; | ||||
|   lastUpdate = 0; | ||||
|   state = 0; | ||||
| } | ||||
| @@ -1370,15 +1380,19 @@ const char *cRecordings::UpdateFileName(void) | ||||
| void cRecordings::Refresh(bool Foreground) | ||||
| { | ||||
|   lastUpdate = time(NULL); // doing this first to make sure we don't miss anything | ||||
|   Lock(); | ||||
|   Clear(); | ||||
|   ChangeState(); | ||||
|   Unlock(); | ||||
|   initial = Count() == 0; // no name checking if the list is initially empty | ||||
|   if (deleted) { | ||||
|      Lock(); | ||||
|      Clear(); | ||||
|      ChangeState(); | ||||
|      Unlock(); | ||||
|      } | ||||
|   ScanVideoDir(cVideoDirectory::Name(), Foreground); | ||||
| } | ||||
|  | ||||
| void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLevel) | ||||
| void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLevel, int DirLevel) | ||||
| { | ||||
|   // Find any new recordings: | ||||
|   cReadDir d(DirName); | ||||
|   struct dirent *e; | ||||
|   while ((Foreground || Running()) && (e = d.Next()) != NULL) { | ||||
| @@ -1397,25 +1411,41 @@ void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLev | ||||
|               } | ||||
|            if (S_ISDIR(st.st_mode)) { | ||||
|               if (endswith(buffer, deleted ? DELEXT : RECEXT)) { | ||||
|                  cRecording *r = new cRecording(buffer); | ||||
|                  if (r->Name()) { | ||||
|                     r->NumFrames(); // initializes the numFrames member | ||||
|                     r->FileSizeMB(); // initializes the fileSizeMB member | ||||
|                     if (deleted) | ||||
|                        r->deleted = time(NULL); | ||||
|                     Lock(); | ||||
|                     Add(r); | ||||
|                     ChangeState(); | ||||
|                     Unlock(); | ||||
|                  if (deleted || initial || !GetByName(buffer)) { | ||||
|                     cRecording *r = new cRecording(buffer); | ||||
|                     if (r->Name()) { | ||||
|                        r->NumFrames(); // initializes the numFrames member | ||||
|                        r->FileSizeMB(); // initializes the fileSizeMB member | ||||
|                        if (deleted) | ||||
|                           r->deleted = time(NULL); | ||||
|                        Lock(); | ||||
|                        Add(r); | ||||
|                        ChangeState(); | ||||
|                        Unlock(); | ||||
|                        } | ||||
|                     else | ||||
|                        delete r; | ||||
|                     } | ||||
|                  else | ||||
|                     delete r; | ||||
|                  } | ||||
|               else | ||||
|                  ScanVideoDir(buffer, Foreground, LinkLevel + Link); | ||||
|                  ScanVideoDir(buffer, Foreground, LinkLevel + Link, DirLevel + 1); | ||||
|               } | ||||
|            } | ||||
|         } | ||||
|   // Handle any vanished recordings: | ||||
|   if (!deleted && !initial && DirLevel == 0) { | ||||
|      for (cRecording *recording = First(); recording; ) { | ||||
|          cRecording *r = recording; | ||||
|          recording = Next(recording); | ||||
|          if (access(r->FileName(), F_OK) != 0) { | ||||
|             Lock(); | ||||
|             Del(r, false); | ||||
|             VanishedRecordings.Add(r); | ||||
|             ChangeState(); | ||||
|             Unlock(); | ||||
|             } | ||||
|          } | ||||
|      } | ||||
| } | ||||
|  | ||||
| bool cRecordings::StateChanged(int &State) | ||||
| @@ -1456,6 +1486,7 @@ bool cRecordings::Update(bool Wait) | ||||
| cRecording *cRecordings::GetByName(const char *FileName) | ||||
| { | ||||
|   if (FileName) { | ||||
|      LOCK_THREAD; | ||||
|      for (cRecording *recording = First(); recording; recording = Next(recording)) { | ||||
|          if (strcmp(recording->FileName(), FileName) == 0) | ||||
|             return recording; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: recording.h 3.1 2013/10/10 12:08:15 kls Exp $ | ||||
|  * $Id: recording.h 3.2 2013/12/24 13:32:18 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __RECORDING_H | ||||
| @@ -41,6 +41,7 @@ enum eRecordingUsage { | ||||
|   }; | ||||
|  | ||||
| void RemoveDeletedRecordings(void); | ||||
| void ClearVanishedRecordings(void); | ||||
| void AssertFreeDiskSpace(int Priority = 0, bool Force = false); | ||||
|      ///< The special Priority value -1 means that we shall get rid of any | ||||
|      ///< deleted recordings faster than normal (because we're cutting). | ||||
| @@ -217,11 +218,12 @@ class cRecordings : public cList<cRecording>, public cThread { | ||||
| private: | ||||
|   static char *updateFileName; | ||||
|   bool deleted; | ||||
|   bool initial; | ||||
|   time_t lastUpdate; | ||||
|   int state; | ||||
|   const char *UpdateFileName(void); | ||||
|   void Refresh(bool Foreground = false); | ||||
|   void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0); | ||||
|   void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0, int DirLevel = 0); | ||||
| protected: | ||||
|   void Action(void); | ||||
| public: | ||||
| @@ -277,6 +279,8 @@ public: | ||||
|        ///< if all recordings have been successfully added to the RecordingsHandler. | ||||
|   }; | ||||
|  | ||||
| /// Any access to Recordings that loops through the list of recordings | ||||
| /// needs to hold a thread lock on this object! | ||||
| extern cRecordings Recordings; | ||||
| extern cRecordings DeletedRecordings; | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								vdr.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								vdr.c
									
									
									
									
									
								
							| @@ -22,7 +22,7 @@ | ||||
|  * | ||||
|  * The project's page is at http://www.tvdr.de | ||||
|  * | ||||
|  * $Id: vdr.c 3.4 2013/10/16 09:33:58 kls Exp $ | ||||
|  * $Id: vdr.c 3.5 2013/12/24 13:19:55 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include <getopt.h> | ||||
| @@ -1369,6 +1369,7 @@ int main(int argc, char *argv[]) | ||||
|  | ||||
|            // Disk housekeeping: | ||||
|            RemoveDeletedRecordings(); | ||||
|            ClearVanishedRecordings(); | ||||
|            cSchedules::Cleanup(); | ||||
|            // Plugins housekeeping: | ||||
|            PluginManager.Housekeeping(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user