diff --git a/Source/Engine/Platform/Linux/LinuxFileSystemWatcher.cpp b/Source/Engine/Platform/Linux/LinuxFileSystemWatcher.cpp index afc00726a..4fcc679df 100644 --- a/Source/Engine/Platform/Linux/LinuxFileSystemWatcher.cpp +++ b/Source/Engine/Platform/Linux/LinuxFileSystemWatcher.cpp @@ -10,6 +10,7 @@ #include "Engine/Core/Math/Math.h" #include "Engine/Core/Collections/Dictionary.h" #include "Engine/Core/Types/Pair.h" +#include "Engine/Utilities/StringConverter.h" #include #include #include @@ -25,8 +26,8 @@ namespace FileSystemWatchers bool ThreadActive; int WacherFileDescriptor; - constexpr int EVENT_SIZE = sizeof (inotify_event); - constexpr int BUF_LEN = 1024 * ( EVENT_SIZE + 16 ); + constexpr int EVENT_SIZE = sizeof(inotify_event); + constexpr int BUF_LEN = 1024 * (EVENT_SIZE + 16); void AddDirWatcher(const int rootFileDesc, const String& path); void DeleteDirWatcher(const int parentWacherFileDesc, String& dirName); @@ -42,12 +43,9 @@ namespace FileSystemWatchers { FD_ZERO(&set); FD_SET(WacherFileDescriptor, &set); - timeout.tv_sec = 0; timeout.tv_usec = 10000; - int retVal = select(WacherFileDescriptor + 1, &set, NULL, NULL, &timeout); - if(retVal == -1) LOG(Error, "WacherFileDescriptor select failed."); else if(retVal == 0) @@ -56,53 +54,52 @@ namespace FileSystemWatchers } else { - int length = read( WacherFileDescriptor, buffer, BUF_LEN ); - - if ( length < 0 ) + int length = read(WacherFileDescriptor, buffer, BUF_LEN); + if (length < 0) { return 0; LOG(Error, "Failed to read WacherFileDescriptor."); } - - int event_offset = 0; - while ( event_offset < length ) - { + int event_offset = 0; + while (event_offset < length) + { LinuxFileSystemWatcher* watcher; auto action = FileSystemAction::Unknown; - inotify_event* event = reinterpret_cast(&buffer[ event_offset ]); - if ( event->len ) + if (event->len) { auto wacher = Watchers[event->wd]; String name(event->name); - if ( event->mask & IN_CREATE ) + if (event->mask & IN_CREATE) { - if ( event->mask & IN_ISDIR ) + if (event->mask & IN_ISDIR) { - AddDirWatcher(GetRootWatcher(event->wd)->GetWachedDirectoryDescriptor(), wacher.Second.First/name); - } else + AddDirWatcher(GetRootWatcher(event->wd)->GetWachedDirectoryDescriptor(), wacher.Second.First / name); + } + else { GetRootWatcher(event->wd)->OnEvent(name, FileSystemAction::Create); } } - else if ( event->mask & IN_DELETE ) + else if (event->mask & IN_DELETE) { - if ( event->mask & IN_ISDIR ) + if (event->mask & IN_ISDIR) { DeleteDirWatcher(event->wd, name); - } else + } + else { GetRootWatcher(event->wd)->OnEvent(name, FileSystemAction::Delete); } } - else if ( event->mask & IN_MODIFY ) + else if (event->mask & IN_MODIFY) { - if ( event->mask & IN_ISDIR ) + if (event->mask & IN_ISDIR) { - // Do we need this? - } else + } + else { GetRootWatcher(event->wd)->OnEvent(name, FileSystemAction::Modify); } @@ -115,27 +112,20 @@ namespace FileSystemWatchers return 0; } - void AddSubDirWatcher (const int rootFileDesc, const String& parent) + void AddSubDirWatcher(const int rootFileDesc, const String& path) { DIR *dir; struct dirent *entry; - - char c_path[parent.Length() + 1]; - Platform::MemoryCopy(c_path, parent.ToStringAnsi().GetText(),parent.Length()); - c_path[parent.Length()]=0; - - if (!(dir = opendir(c_path))) + const StringAsANSI<250> pathAnsi(*path, path.Length()); + if (!(dir = opendir(pathAnsi.Get()))) return; - while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_DIR) { - char path[1024]; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - - AddDirWatcher(rootFileDesc, parent / String(entry->d_name)); + AddDirWatcher(rootFileDesc, path / String(entry->d_name)); } } closedir(dir); @@ -144,7 +134,6 @@ namespace FileSystemWatchers LinuxFileSystemWatcher* GetRootWatcher(int watcherFileDesc) { if (RootWatchers.ContainsKey(watcherFileDesc)) return RootWatchers[watcherFileDesc]; - return RootWatchers[Watchers[watcherFileDesc].First]; } @@ -156,13 +145,12 @@ namespace FileSystemWatchers void DeleteDirWatcher(const int parentWacherFileDesc, String& dirName) { - if ( Watchers.ContainsKey(parentWacherFileDesc)) + if (Watchers.ContainsKey(parentWacherFileDesc)) { - auto fullPath = Watchers[parentWacherFileDesc].Second.Second->Directory/dirName; - + auto fullPath = Watchers[parentWacherFileDesc].Second.Second->Directory / dirName; for (auto& watcher : Watchers) { - if(watcher.Value.Second.First.Compare(fullPath) == 0) + if (watcher.Value.Second.First.Compare(fullPath) == 0) { Delete(watcher.Value.Second.Second); } @@ -174,38 +162,21 @@ namespace FileSystemWatchers LinuxFileSystemWatcher::LinuxFileSystemWatcher(const String& directory, bool withSubDirs, int rootWatcher) : FileSystemWatcherBase(directory, withSubDirs) { - // Register FileSystemWatchers::Locker.Lock(); - - if(withSubDirs) - { - for (const auto& watcher : FileSystemWatchers::Watchers) - { - LOG(Info, "Watcher:{} .", watcher.Key); - } - } if (!FileSystemWatchers::Thread) { FileSystemWatchers::WacherFileDescriptor = inotify_init(); - - if ( FileSystemWatchers::WacherFileDescriptor > 0 ) + if (FileSystemWatchers::WacherFileDescriptor > 0) { FileSystemWatchers::ThreadActive = true; FileSystemWatchers::Thread = ThreadSpawner::Start(FileSystemWatchers::Run, TEXT("File System Watchers"), ThreadPriority::BelowNormal); } } - - if ( FileSystemWatchers::WacherFileDescriptor > 0 ) + if (FileSystemWatchers::WacherFileDescriptor > 0) { - char c_path[directory.Length() + 1]; - Platform::MemoryCopy(c_path, directory.ToStringAnsi().GetText(),directory.Length()); - c_path[directory.Length()]=0; - - LOG(Info, "Adding watcher for directory {}.", Directory); - WachedDirectory = inotify_add_watch( FileSystemWatchers::WacherFileDescriptor, c_path, IN_MODIFY | IN_CREATE | IN_DELETE ); - + const StringAsANSI<250> directoryAnsi(*directory, directory.Length()); + WachedDirectory = inotify_add_watch(FileSystemWatchers::WacherFileDescriptor, directoryAnsi.Get(), IN_MODIFY | IN_CREATE | IN_DELETE); FileSystemWatchers::Watchers[WachedDirectory] = Pair>(rootWatcher, Pair(directory, this)); - if (withSubDirs) { FileSystemWatchers::RootWatchers[WachedDirectory] = this; @@ -217,31 +188,26 @@ LinuxFileSystemWatcher::LinuxFileSystemWatcher(const String& directory, bool wit LinuxFileSystemWatcher::~LinuxFileSystemWatcher() { + FileSystemWatchers::Locker.Lock(); if (FileSystemWatchers::WacherFileDescriptor > 0) { - LOG(Info, "Removing watcher for directory {}.", Directory); - inotify_rm_watch( FileSystemWatchers::WacherFileDescriptor, WachedDirectory ); - - FileSystemWatchers::Locker.Lock(); - if (FileSystemWatchers::RootWatchers.ContainsKey(WachedDirectory)) - { - FileSystemWatchers::RootWatchers.Remove(WachedDirectory); - } + inotify_rm_watch(FileSystemWatchers::WacherFileDescriptor, WachedDirectory); + FileSystemWatchers::RootWatchers.Remove(WachedDirectory); FileSystemWatchers::Watchers.Remove(WachedDirectory); - FileSystemWatchers::Locker.Unlock(); } - - FileSystemWatchers::Locker.Lock(); - if (FileSystemWatchers::Watchers.IsEmpty() && FileSystemWatchers::Thread) + if (FileSystemWatchers::RootWatchers.IsEmpty() && FileSystemWatchers::Thread) { FileSystemWatchers::ThreadActive = false; FileSystemWatchers::Thread->Join(); Delete(FileSystemWatchers::Thread); FileSystemWatchers::Thread = nullptr; - close( FileSystemWatchers::WacherFileDescriptor ); + close(FileSystemWatchers::WacherFileDescriptor); + FileSystemWatchers::WacherFileDescriptor = 0; + for (auto e : FileSystemWatchers::Watchers) + Delete(e.Value.Second.Second); + FileSystemWatchers::Watchers.Clear(); } FileSystemWatchers::Locker.Unlock(); } #endif -