[vlc-commits] [Git][videolan/vlc][master] macosx: Require re-fetch of library items if deletion received during pending fetch

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Tue Oct 13 06:28:03 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
3c3b719f by Claudio Cambra at 2026-10-13T08:17:44+02:00
macosx: Require re-fetch of library items if deletion received during pending fetch

Ignoring the deletion because the item isn't present in the cache can lead to a pre-existing fetch being applied onto the cache and then displaying the item that was subject to deletion. To resolve this, re-fetch if there is a pending full-list fetch

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -


1 changed file:

- modules/gui/macosx/library/VLCLibraryModel.m


Changes:

=====================================
modules/gui/macosx/library/VLCLibraryModel.m
=====================================
@@ -1273,15 +1273,15 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
 
 - (void)refreshCachedShowForEpisodeID:(int64_t)episodeID
 {
-    NSNumber * const showID = _showIDsByEpisodeID[@(episodeID)];
-    if (showID == nil) {
-        return;
-    }
     if ([self invalidateCacheUpdateForGetter:@selector(cachedListOfShows)]) {
-        // A parent-only lookup would lose other shows in the pending full list.
+        // The pending list may contain an episode not mapped by the old cache.
         [self resetCachedListOfShows];
         return;
     }
+    NSNumber * const showID = _showIDsByEpisodeID[@(episodeID)];
+    if (showID == nil) {
+        return;
+    }
     const BOOL refreshPending = _showRefreshTokens[showID] != nil;
     _showRefreshTokens[showID] = NSObject.new;
     if (!refreshPending) {
@@ -1782,8 +1782,20 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
             return;
         }
 
-        // Not found in any cache
-        action(nil, NSNotFound, nil, NSNotFound);
+        // An ongoing medialibrary fetch may have retrieved this item without
+        // writing it to the cache yet. Restart pending fetches so an outdated
+        // result cannot restore a deleted item or overwrite an updated one.
+        // Its media type is unknown here, so check all four caches, but only
+        // restart fetches already in progress
+        const SEL getters[] = {
+            @selector(cachedAudioMedia),
+            @selector(cachedRecentAudioMedia),
+            @selector(cachedVideoMedia),
+            @selector(cachedRecentMedia),
+        };
+        [self performCacheMutationForGetters:getters count:4 block:^{
+            action(nil, NSNotFound, nil, NSNotFound);
+        }];
     });
 }
 
@@ -2112,36 +2124,35 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
     NSParameterAssert(reloadPending != NULL);
 
     dispatch_barrier_async(queue, ^{
-        NSArray * const cache = cacheGetter();
-
-        if (cache == nil) {
-            return;
-        }
+        [self performCacheMutationForGetter:getter block:^{
+            NSArray * const cache = cacheGetter();
 
-        if (*reloadPending) {
-            cacheRefresh();
-            return;
-        }
+            if (cache == nil) {
+                return;
+            }
 
-        const NSUInteger audioGroupIndex = [self indexForAudioGroupInCache:cache
-                                                                withItemId:itemId];
-        if (audioGroupIndex == NSNotFound) {
-            NSLog(@"Did not find audio group item with id %lli in cache.", itemId);
-            return;
-        }
+            if (*reloadPending) {
+                cacheRefresh();
+                return;
+            }
 
-        const id<VLCMediaLibraryAudioGroupProtocol> audioGroupItem = cache[audioGroupIndex];
+            const NSUInteger audioGroupIndex = [self indexForAudioGroupInCache:cache
+                                                                    withItemId:itemId];
+            if (audioGroupIndex == NSNotFound) {
+                NSLog(@"Did not find audio group item with id %lli in cache.", itemId);
+                return;
+            }
 
-        // Create mutable copy for modification
-        NSMutableArray * const mutableAudioGroupCache = [cache mutableCopy];
-        [mutableAudioGroupCache removeObjectAtIndex:audioGroupIndex];
+            const id<VLCMediaLibraryAudioGroupProtocol> audioGroupItem = cache[audioGroupIndex];
 
-        [self performCacheMutationForGetter:getter block:^{
+            // Create mutable copy for modification
+            NSMutableArray * const mutableAudioGroupCache = [cache mutableCopy];
+            [mutableAudioGroupCache removeObjectAtIndex:audioGroupIndex];
             cacheSetter(mutableAudioGroupCache.copy);
-        }];
 
-        [self performAfterCacheWritesOnQueue:queue block:^{
-            [self.changeDelegate notifyChange:notificationName withObject:audioGroupItem];
+            [self performAfterCacheWritesOnQueue:queue block:^{
+                [self.changeDelegate notifyChange:notificationName withObject:audioGroupItem];
+            }];
         }];
     });
 }
@@ -2279,34 +2290,34 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
     const int64_t itemId = p_event->modification.i_entity_id;
 
     dispatch_barrier_async(_groupCacheModificationQueue, ^{
-        NSArray<VLCMediaLibraryGroup *> * const cachedGroups = self->_cachedListOfGroups;
-        if (cachedGroups == nil) {
-            return;
-        }
+        [self performCacheMutationForGetter:@selector(cachedListOfGroups) block:^{
+            NSArray<VLCMediaLibraryGroup *> * const cachedGroups = self->_cachedListOfGroups;
+            if (cachedGroups == nil) {
+                return;
+            }
 
-        const NSUInteger groupIdx =
-            [cachedGroups indexOfObjectPassingTest:^BOOL(VLCMediaLibraryGroup * const group,
-                                                         const NSUInteger __unused idx,
-                                                         BOOL * const __unused stop) {
-            return group.libraryID == itemId;
-        }];
+            const NSUInteger groupIdx =
+                [cachedGroups indexOfObjectPassingTest:^BOOL(VLCMediaLibraryGroup * const group,
+                                                             const NSUInteger __unused idx,
+                                                             BOOL * const __unused stop) {
+                return group.libraryID == itemId;
+            }];
 
-        if (groupIdx == NSNotFound) {
-            NSLog(@"Could not handle deletion of group with id %lld in model", itemId);
-            return;
-        }
+            if (groupIdx == NSNotFound) {
+                NSLog(@"Could not handle deletion of group with id %lld in model", itemId);
+                return;
+            }
 
-        VLCMediaLibraryGroup * const groupToDelete = cachedGroups[groupIdx];
+            VLCMediaLibraryGroup * const groupToDelete = cachedGroups[groupIdx];
 
-        NSMutableArray * const mutableGroups = cachedGroups.mutableCopy;
-        [mutableGroups removeObjectAtIndex:groupIdx];
-        [self performCacheMutationForGetter:@selector(cachedListOfGroups) block:^{
+            NSMutableArray * const mutableGroups = cachedGroups.mutableCopy;
+            [mutableGroups removeObjectAtIndex:groupIdx];
             self->_cachedListOfGroups = mutableGroups.copy;
-        }];
 
-        [self performAfterCacheWritesOnQueue:self->_groupCacheModificationQueue block:^{
-            [self->_defaultNotificationCenter postNotificationName:VLCLibraryModelGroupDeleted
-                                                            object:groupToDelete];
+            [self performAfterCacheWritesOnQueue:self->_groupCacheModificationQueue block:^{
+                [self->_defaultNotificationCenter postNotificationName:VLCLibraryModelGroupDeleted
+                                                                object:groupToDelete];
+            }];
         }];
     });
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/3c3b719fc6be39c796e9312b4157aa701d7f7bbc

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/3c3b719fc6be39c796e9312b4157aa701d7f7bbc
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list