diff --git a/far/changelog b/far/changelog index 9d6d4d654e..4768e9c14a 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,8 @@ +-------------------------------------------------------------------------------- +drkns 2024-10-29 02:35:48+00:00 - build 6386 + +1. Continue 6385.5. + -------------------------------------------------------------------------------- drkns 2024-10-26 20:17:00+01:00 - build 6385 diff --git a/far/filesystemwatcher.cpp b/far/filesystemwatcher.cpp index a78af4613a..97a1f8d897 100644 --- a/far/filesystemwatcher.cpp +++ b/far/filesystemwatcher.cpp @@ -69,7 +69,7 @@ class background_watcher: public singleton m_Clients.emplace_back(Client); - m_Synchronised = false; + m_Synchronised.reset(); if (!m_Thread.joinable() || m_Thread.is_signaled()) m_Thread = os::thread(&background_watcher::process, this); @@ -79,13 +79,17 @@ class background_watcher: public singleton void remove(const FileSystemWatcher* Client) { - SCOPED_ACTION(std::scoped_lock)(m_CS); + { + SCOPED_ACTION(std::scoped_lock)(m_CS); - std::erase(m_Clients, Client); + std::erase(m_Clients, Client); - m_Synchronised = false; + m_Synchronised.reset(); + m_Update.set(); + } - m_Update.set(); + // We have to ensure that the client event handle is no longer used by the watcher before letting the client go + m_Synchronised.wait(); } private: @@ -101,8 +105,10 @@ class background_watcher: public singleton { SCOPED_ACTION(std::scoped_lock)(m_CS); - if (!m_Synchronised) + if (!m_Synchronised.is_signaled()) { + SCOPE_EXIT{ m_Synchronised.set(); }; + if (m_Clients.empty()) { LOGDEBUG(L"FS Watcher exit"sv); @@ -121,7 +127,6 @@ class background_watcher: public singleton return Handle; }); - m_Synchronised = true; } } @@ -138,7 +143,7 @@ class background_watcher: public singleton { SCOPED_ACTION(std::scoped_lock)(m_CS); - if (!m_Synchronised) + if (!m_Synchronised.is_signaled()) { PendingHandle = Handles[Result]; continue; @@ -167,8 +172,9 @@ class background_watcher: public singleton os::critical_section m_CS; os::event m_Update{ os::event::type::automatic, os::event::state::nonsignaled }; + os::event m_Synchronised{ os::event::type::manual, os::event::state::nonsignaled }; std::vector m_Clients; - std::atomic_bool m_Exit{}, m_Synchronised{}; + std::atomic_bool m_Exit{}; os::thread m_Thread; }; @@ -225,9 +231,20 @@ FileSystemWatcher::~FileSystemWatcher() m_DirectoryHandle = {}; - m_Event.wait(); + switch (const auto Status = m_Overlapped.Internal) + { + case STATUS_NOTIFY_CLEANUP: + case STATUS_NOTIFY_ENUM_DIR: + break; + + case STATUS_PENDING: + (void)get_result(); + break; - assert(m_Overlapped.Internal == STATUS_NOTIFY_CLEANUP); + default: + LOGDEBUG(L"Overlapped.Internal: {}"sv, os::error_state{ ERROR_SUCCESS, static_cast(m_Overlapped.Internal) }); + break; + } } } diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 64b23ba542..6d296867c5 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -6385 +6386