shell_integration on Windows: Avoid too many RETRIEVE_FILE_STATUS following UPDATE_VI...
authorJocelyn Turcotte <jturcotte@woboq.com>
Tue, 5 May 2015 09:24:01 +0000 (11:24 +0200)
committerJocelyn Turcotte <jturcotte@woboq.com>
Wed, 6 May 2015 14:48:34 +0000 (16:48 +0200)
Do not request the status of all entries in the cache. Instead force
explorer to request the ones that it deems necessary by keeping the old
statuses in a separate dictionary which are only used while the new status
arrives.

binary
shell_integration/windows/OCUtil/RemotePathChecker.cpp
shell_integration/windows/OCUtil/RemotePathChecker.h

diff --git a/binary b/binary
index 1fb9ddfa9a9a1b4dbc447eee10dbed89172d968a..8b72648a939580995facefcd5f635388000ab4d1 160000 (submodule)
--- a/binary
+++ b/binary
@@ -1 +1 @@
-Subproject commit 1fb9ddfa9a9a1b4dbc447eee10dbed89172d968a
+Subproject commit 8b72648a939580995facefcd5f635388000ab4d1
index 0dda646092e2914716ea390215753edfdb3d03d5..e9ed9fd3ff56888cf162bf459483234f3943ce08 100644 (file)
@@ -98,6 +98,8 @@ void RemotePathChecker::workerThreadLoop()
                             ++it;
                         }
                     }
+                    // Assume that we won't need this at this point, UNREGISTER_PATH is rare
+                    _oldCache.clear();
                 }
                                SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH | SHCNF_FLUSHNOWAIT, responsePath.data(), NULL);
             } else if (StringUtil::begins_with(response, wstring(L"STATUS:")) ||
@@ -132,20 +134,25 @@ void RemotePathChecker::workerThreadLoop()
                        }
                        else if (StringUtil::begins_with(response, wstring(L"UPDATE_VIEW"))) {
                                std::unique_lock<std::mutex> lock(_mutex);
-                auto cache = _cache; // Make a copy of the cache under the mutex
+                // Keep the old states to continue having something to display while the new state is
+                // requested from the client, triggered by clearing _cache.
+                _oldCache.insert(_cache.cbegin(), _cache.cend());
+
+                // Swap to make a copy of the cache under the mutex and clear the one stored.
+                std::unordered_map<std::wstring, FileState> cache;
+                swap(cache, _cache);
                 lock.unlock();
-                               // Request a status for all the items in the cache.
-                               for (auto it = cache.begin(); it != cache.end(); ++it) {
-                                       if (!socket.SendMsg(wstring(L"RETRIEVE_FILE_STATUS:" + it->first + L'\n').data())) {
-                                               break;
-                                       }
-                               }
-                       }
+                // Let explorer know about the invalidated cache entries, it will re-request the ones it needs.
+                for (auto it = cache.begin(); it != cache.end(); ++it) {
+                    SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, it->first.data(), NULL);
+                }
+            }
                }
 
                if (socket.Event() == INVALID_HANDLE_VALUE) {
                        std::unique_lock<std::mutex> lock(_mutex);
                        _cache.clear();
+            _oldCache.clear();
                        _watchedDirectories.clear();
                        _connected = connected = false;
                }
@@ -198,11 +205,17 @@ bool RemotePathChecker::IsMonitoredPath(const wchar_t* filePath, int* state)
         return true;
     }
 
+    // Re-request the status while we display what we have in _oldCache
     _pending.push(filePath);
+
+    it = _oldCache.find(path);
+    bool foundInOldCache = it != _oldCache.end();
+    if (foundInOldCache)
+        *state = it->second;
+
     lock.unlock();
     SetEvent(_newQueries);
-    return false;
-
+    return foundInOldCache;
 }
 
 RemotePathChecker::FileState RemotePathChecker::_StrToFileState(const std::wstring &str)
index 7d7decdcf22c9a62b0395f810011a458f34353f7..8df2c358a80eab20c0c000da45f4629da337ba33 100644 (file)
@@ -52,6 +52,7 @@ private:
     std::queue<std::wstring> _pending;
 
     std::unordered_map<std::wstring, FileState> _cache;
+    std::unordered_map<std::wstring, FileState> _oldCache;
     std::vector<std::wstring> _watchedDirectories;
     bool _connected;