Thread safety and cache integrity improvements#911
Open
sreckoskocilic wants to merge 7 commits intofman-users:mainfrom
Open
Thread safety and cache integrity improvements#911sreckoskocilic wants to merge 7 commits intofman-users:mainfrom
sreckoskocilic wants to merge 7 commits intofman-users:mainfrom
Conversation
…paring two tuples, every equality check returns True - master -> main branch fix - prepare_trash now calls self.move_to_trash instead of self.delete, so plugin subclasses won't permanently delete files when the user expects trashing - NotImplementedError - unrecognized platforms fail fast with a clear message instead of a cryptic NameError - removed shadowing basename import - get_column_widths uses range so plugin-added columns get their widths saved/restored
…it__ always runs, even on exception. - util/qt/__init__.py — Added missing c_void_p import from ctypes, fixing a macOS runtime crash. - table.py — Fixed off-by-one: bounds check now rejects len + 1 correctly. - widgets.py — Added null guard on _main_window before accessing it in state change handler.
…ved, so a/b/c/../../d correctly becomes a/d. - session.py — Removed dead _get_startup_message method (duplicated by _show_startup_messages)
- Add Cache._lock with generation counter to detect stale query results - Use RLock per-attr in CacheItem for reentrant nested queries - Split CachedIterator locking: _lock for items, _source_lock for source - Always wrap iterdir results in CachedIterator for uniform cache ops - Protect Event callbacks with Lock, snapshot before iteration - Add _tasks_lock to Executor for safe quit/submit races - Use thread-local for _override_file_under_cursor (was monkey-patching) - Snapshot _listeners list before iteration in DirectoryPane._broadcast - Lock notify_file_changed callback snapshot in FileSystem - Add _cache_lock to IconProvider for thread-safe surrogate creation - Cap _already_visited set at 512, convert recursion to iteration - Add shutdown() to SortedFileSystemModel for clean signal disconnect - Replace assert with RuntimeError in diff.py for production safety - Fix missing _m_files update in record_files.py for filtered entries - Change Task.Canceled base from KeyboardInterrupt to Exception - Add APPDATA null guard on Windows - 47 new concurrency and cache invalidation tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fs_cache.pyrewrite — full lock hierarchy documented and enforced:Cache._lock→CacheItem._children_lock→CacheItem._attr_locks_lock→ per-attrRLock. Generation counter detects invalidation duringquery()and retries. Newmutate()andclear_attr()methods for atomic cache operationsCachedIteratorconcurrency fix — split into_lock(protects items/counts) and_source_lock(serializes source advancement).remove()/append()use proper count clamping.get_next()re-scans after acquiring_source_lockto avoid missed itemsmother_fs.py—_remove_from_parent/_add_to_parentusecache.mutate()instead of get-then-modify pattern;_clear_parent_statinvalidates parent'sstatandiconcache on add/remove;notify_file_addedclears child cache before notification;iterdiralways wraps inCachedIteratorrecord_files.py— missing_m_files[url] = file_assignment when file passes filter but isn't in_m_filesyetEventsystem —add_callback/remove_callback/triggerprotected byLock;triggersnapshots callback list before iterationDirectoryPane._broadcast— iterates overlist(self._listeners)snapshot to avoid mutation during iterationfile_under_cursorcontext manager — thread-local storage replaces monkey-patched method;try/finallyensures cleanupicon_provider.py—Lockaround suffix cache dict;.message→str(e)forFontErrorcompatibilitymodel/__init__.py—_MAX_VISITEDcap,sourceModel()null guard, iterative parent traversal,shutdown()method (shared with critical crashes branch)model/diff.py— 5assertstatements replaced withraise RuntimeErrorfor production safetyqt/thread.py—Executorcleanup: removed bareexcept, addedKeyErrorguard on timer cleanup,deleteLater()ensures Qt event processingfman/__init__.py—APPDATAenv var check on Windows;CanceledextendsExceptionnotKeyboardInterrupt; listener iteration snapshotsfs.py—FileSystemdocstring added;_file_changed_callbacksprotected by lock with snapshot-then-iterate pattern;copy/movedocstrings clarify they receive full URLstest_fs_cache.py(14 tests),test_mother_fs.py(11 tests),test_fs.py(3 tests) covering cache concurrency, generation-based invalidation, CachedIterator thread safety, and event callback thread safetyTest plan