1212#import " FICImageTableChunk.h"
1313#import " FICImageTableEntry.h"
1414#import " FICUtilities.h"
15+ #import < libkern/OSAtomic.h>
1516
1617#import " FICImageCache+FICErrorLogging.h"
1718
@@ -62,7 +63,8 @@ @interface FICImageTable () {
6263 NSMutableOrderedSet *_MRUEntries;
6364 NSCountedSet *_inUseEntries;
6465 NSDictionary *_imageFormatDictionary;
65-
66+ int32_t _metadataVersion;
67+
6668 NSString *_fileDataProtectionMode;
6769 BOOL _canAccessData;
6870}
@@ -683,6 +685,9 @@ - (void)saveMetadata {
683685 [_sourceImageMap copy ], FICImageTableContextMapKey,
684686 [[_MRUEntries array ] copy ], FICImageTableMRUArrayKey,
685687 [_imageFormatDictionary copy ], FICImageTableFormatKey, nil ];
688+
689+ __block int32_t metadataVersion = OSAtomicIncrement32 (&_metadataVersion);
690+
686691 [_lock unlock ];
687692
688693 static dispatch_queue_t __metadataQueue = nil ;
@@ -692,7 +697,18 @@ - (void)saveMetadata {
692697 });
693698
694699 dispatch_async (__metadataQueue, ^{
700+ // Cancel serialization if a new metadata version is queued to be saved
701+ if (metadataVersion != _metadataVersion) {
702+ return ;
703+ }
704+
695705 NSData *data = [NSPropertyListSerialization dataWithPropertyList: metadataDictionary format: NSPropertyListBinaryFormat_v1_0 options: 0 error: NULL ];
706+
707+ // Cancel disk writing if a new metadata version is queued to be saved
708+ if (metadataVersion != _metadataVersion) {
709+ return ;
710+ }
711+
696712 BOOL fileWriteResult = [data writeToFile: [self metadataFilePath ] atomically: NO ];
697713 if (fileWriteResult == NO ) {
698714 NSString *message = [NSString stringWithFormat: @" *** FIC Error: %s couldn't write metadata for format %@ " , __PRETTY_FUNCTION__, [_imageFormat name ]];
0 commit comments