[FarGroup/FarManager] master: Improve FS monitoring error handling in corner cases (d984c8380)

0 views
Skip to first unread message

farg...@farmanager.com

unread,
Mar 9, 2026, 6:45:56 PMMar 9
to farco...@googlegroups.com
Repository : https://github.com/FarGroup/FarManager
On branch : master
Link : https://github.com/FarGroup/FarManager/commit/d984c8380071322dd5de4a2ebee5949a9cd1e2aa

>---------------------------------------------------------------

commit d984c8380071322dd5de4a2ebee5949a9cd1e2aa
Author: Alex Alabuzhev <alab...@gmail.com>
Date: Mon Mar 9 22:29:56 2026 +0000

Improve FS monitoring error handling in corner cases


>---------------------------------------------------------------

d984c8380071322dd5de4a2ebee5949a9cd1e2aa
far/changelog | 5 +++++
far/filelist.cpp | 4 ++++
far/filesystemwatcher.cpp | 52 +++++++++++++++++++++++++++++++----------------
far/filesystemwatcher.hpp | 3 +++
far/vbuild.m4 | 2 +-
5 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/far/changelog b/far/changelog
index a758740d6..bd56b590d 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+drkns 2026-03-09 22:24:56+00:00 - build 6656
+
+1. Improve FS monitoring error handling in corner cases.
+
--------------------------------------------------------------------------------
drkns 2026-03-09 19:09:32+00:00 - build 6655

diff --git a/far/filelist.cpp b/far/filelist.cpp
index 32d50b0ca..7da0b3f2a 100644
--- a/far/filelist.cpp
+++ b/far/filelist.cpp
@@ -1669,6 +1669,10 @@ bool FileList::ProcessKey(const Manager::Key& Key)
AnotherPanel->Redraw();
}
}
+
+ if (FSWatcher)
+ FSWatcher->restart_if_needed();
+
break;
}

diff --git a/far/filesystemwatcher.cpp b/far/filesystemwatcher.cpp
index 0a585707f..c2f4a0313 100644
--- a/far/filesystemwatcher.cpp
+++ b/far/filesystemwatcher.cpp
@@ -211,21 +211,13 @@ static os::handle open(const string_view Directory)
FileSystemWatcher::FileSystemWatcher(const string_view EventId, const string_view Directory, const bool WatchSubtree):
m_EventId(EventId),
m_Directory(nt_path(Directory)),
- m_WatchSubtree(WatchSubtree),
- m_DirectoryHandle(open(m_Directory))
+ m_WatchSubtree(WatchSubtree)
{
- if (!m_DirectoryHandle)
- {
- LOGWARNING(L"Skip monitoring of {}"sv, Directory);
- return;
- }
-
m_Overlapped.hEvent = m_Event.native_handle();
-
background_watcher::instance().add(this);

- LOGDEBUG(L"Start monitoring {} {}"sv, m_Directory, WatchSubtree? L"tree"sv : L"directory"sv);
- read_async();
+ if (open_directory())
+ read_async();
}

FileSystemWatcher::~FileSystemWatcher()
@@ -265,9 +257,28 @@ FileSystemWatcher::~FileSystemWatcher()
}
}

+void FileSystemWatcher::restart_if_needed()
+{
+ SCOPED_ACTION(std::scoped_lock)(m_CS);
+
+ if (m_DirectoryHandle)
+ return;
+
+ LOGINFO(L"Attempting to restart monitoring of {}"sv, m_Directory);
+
+ if (open_directory())
+ read_async();
+}
+
+bool FileSystemWatcher::open_directory()
+{
+ m_DirectoryHandle = open(m_Directory);
+ return m_DirectoryHandle != nullptr;
+}
+
void FileSystemWatcher::read_async()
{
- m_Event.reset();
+ LOGDEBUG(L"Start monitoring {} {}"sv, m_Directory, m_WatchSubtree? L"tree"sv : L"directory"sv);

if (!ReadDirectoryChangesW(
m_DirectoryHandle.native_handle(),
@@ -327,13 +338,18 @@ bool FileSystemWatcher::get_result() const

void FileSystemWatcher::callback_notify()
{
- if (!m_DirectoryHandle)
- return;
-
- if (!get_result())
{
- LOGDEBUG(L"Stop monitoring {}"sv, m_Directory);
- return;
+ SCOPE_EXIT{ m_Event.reset(); };
+
+ if (!m_DirectoryHandle)
+ return;
+
+ if (!get_result())
+ {
+ LOGWARNING(L"Stop monitoring {}"sv, m_Directory);
+ m_DirectoryHandle = {};
+ return;
+ }
}

LOGDEBUG(L"Change event in {}"sv, m_Directory);
diff --git a/far/filesystemwatcher.hpp b/far/filesystemwatcher.hpp
index f7165b619..0edd823f1 100644
--- a/far/filesystemwatcher.hpp
+++ b/far/filesystemwatcher.hpp
@@ -54,9 +54,12 @@ public:
FileSystemWatcher(string_view EventId, string_view Directory, bool WatchSubtree);
~FileSystemWatcher();

+ void restart_if_needed();
+
private:
friend class background_watcher;

+ bool open_directory();
void read_async();
bool get_result() const;
void callback_notify();
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index cbd5c4970..b12244baf 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6655
+6656


Reply all
Reply to author
Forward
0 new messages