#pragma once #include #include #include #include #include #include #include "envoy/api/api.h" #include "envoy/event/dispatcher.h" #include "envoy/filesystem/watcher.h" #include "envoy/network/io_handle.h" #include "common/api/os_sys_calls_impl.h" #include "common/buffer/buffer_impl.h" #include "common/common/fmt.h" #include "common/common/logger.h" #include "common/common/thread_impl.h" #include "common/network/io_socket_handle_impl.h" #include "absl/container/node_hash_map.h" namespace Envoy { namespace Filesystem { class WatcherImpl : public Watcher, Logger::Loggable { public: WatcherImpl(Event::Dispatcher& dispatcher, Api::Api& api); ~WatcherImpl(); // Filesystem::Watcher void addWatch(absl::string_view path, uint32_t events, OnChangedCb cb) override; private: static void issueFirstRead(ULONG_PTR param); static void directoryChangeCompletion(DWORD err, DWORD num_bytes, LPOVERLAPPED overlapped); static void endDirectoryWatch(Network::IoHandle& io_handle, HANDLE hEvent); void watchLoop(); void onDirectoryEvent(); struct FileWatch { // store the wide character string for ReadDirectoryChangesW std::wstring file_; uint32_t events_; OnChangedCb cb_; }; typedef std::function CbClosure; struct DirectoryWatch { OVERLAPPED overlapped_; std::list watches_; HANDLE dir_handle_; std::vector buffer_; WatcherImpl* watcher_; }; typedef std::unique_ptr DirectoryWatchPtr; Api::Api& api_; absl::node_hash_map callback_map_; Network::IoHandlePtr read_handle_; Network::IoHandlePtr write_handle_; Thread::ThreadPtr watch_thread_; Thread::ThreadFactoryImplWin32 thread_factory_; HANDLE thread_exit_event_; std::vector dir_watch_complete_events_; std::atomic keep_watching_; concurrency::concurrent_queue active_callbacks_; Api::OsSysCallsImpl& os_sys_calls_; std::wstring_convert> wstring_converter_; }; } // namespace Filesystem } // namespace Envoy