1c540156cSNicolas Bonnefon #ifndef INOTIFYWATCHTOWERDRIVER_H 2c540156cSNicolas Bonnefon #define INOTIFYWATCHTOWERDRIVER_H 3c540156cSNicolas Bonnefon 4b278d183SNicolas Bonnefon #include <memory> 5b278d183SNicolas Bonnefon #include <mutex> 6b278d183SNicolas Bonnefon #include <vector> 7c540156cSNicolas Bonnefon 8f09fa651SNicolas Bonnefon template <typename Driver> 9b278d183SNicolas Bonnefon class ObservedFile; 10f09fa651SNicolas Bonnefon template <typename Driver> 11b278d183SNicolas Bonnefon class ObservedFileList; 12b278d183SNicolas Bonnefon 13b278d183SNicolas Bonnefon class INotifyWatchTowerDriver { 14c540156cSNicolas Bonnefon public: 15b278d183SNicolas Bonnefon class FileId { 16b278d183SNicolas Bonnefon public: 17b278d183SNicolas Bonnefon friend class INotifyWatchTowerDriver; 18b278d183SNicolas Bonnefon 19dc7f5916SNicolas Bonnefon FileId() { wd_ = -1; } 20b278d183SNicolas Bonnefon bool operator==( const FileId& other ) const 21b278d183SNicolas Bonnefon { return wd_ == other.wd_; } 22b278d183SNicolas Bonnefon private: 23b278d183SNicolas Bonnefon FileId( int wd ) { wd_ = wd; } 24dc7f5916SNicolas Bonnefon int wd_; 25c540156cSNicolas Bonnefon }; 26b278d183SNicolas Bonnefon class DirId { 27b278d183SNicolas Bonnefon public: 28b278d183SNicolas Bonnefon friend class INotifyWatchTowerDriver; 29b278d183SNicolas Bonnefon 30dc7f5916SNicolas Bonnefon DirId() { wd_ = -1; } 31b278d183SNicolas Bonnefon bool operator==( const DirId& other ) const 32b278d183SNicolas Bonnefon { return wd_ == other.wd_; } 33b278d183SNicolas Bonnefon private: 34b278d183SNicolas Bonnefon DirId( int wd ) { wd_ = wd; } 35dc7f5916SNicolas Bonnefon int wd_; 36c540156cSNicolas Bonnefon }; 37b278d183SNicolas Bonnefon class SymlinkId { 38b278d183SNicolas Bonnefon public: 39b278d183SNicolas Bonnefon friend class INotifyWatchTowerDriver; 40b278d183SNicolas Bonnefon 41dc7f5916SNicolas Bonnefon SymlinkId() { wd_ = -1; } 42b278d183SNicolas Bonnefon bool operator==( const SymlinkId& other ) const 43b278d183SNicolas Bonnefon { return wd_ == other.wd_; } 44b278d183SNicolas Bonnefon private: 45b278d183SNicolas Bonnefon SymlinkId( int wd ) { wd_ = wd; } 46dc7f5916SNicolas Bonnefon int wd_; 47c540156cSNicolas Bonnefon }; 48c540156cSNicolas Bonnefon 49*58f443c7SNicolas Bonnefon #ifdef HAS_TEMPLATE_ALIASES 50f09fa651SNicolas Bonnefon using INotifyObservedFile = ObservedFile<INotifyWatchTowerDriver>; 51f09fa651SNicolas Bonnefon using INotifyObservedFileList = ObservedFileList<INotifyWatchTowerDriver>; 52*58f443c7SNicolas Bonnefon #else 53*58f443c7SNicolas Bonnefon typedef ObservedFile<INotifyWatchTowerDriver> INotifyObservedFile; 54*58f443c7SNicolas Bonnefon typedef ObservedFileList<INotifyWatchTowerDriver> INotifyObservedFileList; 55*58f443c7SNicolas Bonnefon #endif 56f09fa651SNicolas Bonnefon 57f09fa651SNicolas Bonnefon // Default constructor 58c540156cSNicolas Bonnefon INotifyWatchTowerDriver(); 59b0345991SNicolas Bonnefon ~INotifyWatchTowerDriver(); 60b0345991SNicolas Bonnefon 61b0345991SNicolas Bonnefon // No copy/assign/move please 62b0345991SNicolas Bonnefon INotifyWatchTowerDriver( const INotifyWatchTowerDriver& ) = delete; 63b0345991SNicolas Bonnefon INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver& ) = delete; 64b0345991SNicolas Bonnefon INotifyWatchTowerDriver( const INotifyWatchTowerDriver&& ) = delete; 65b0345991SNicolas Bonnefon INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver&& ) = delete; 66c540156cSNicolas Bonnefon 67b278d183SNicolas Bonnefon FileId addFile( const std::string& file_name ); 68b278d183SNicolas Bonnefon SymlinkId addSymlink( const std::string& file_name ); 69b278d183SNicolas Bonnefon DirId addDir( const std::string& file_name ); 70c540156cSNicolas Bonnefon 71b278d183SNicolas Bonnefon void removeFile( const FileId& file_id ); 72b278d183SNicolas Bonnefon void removeSymlink( const SymlinkId& symlink_id ); 73c540156cSNicolas Bonnefon 74f09fa651SNicolas Bonnefon std::vector<INotifyObservedFile*> waitAndProcessEvents( 75f09fa651SNicolas Bonnefon INotifyObservedFileList* list, 76b278d183SNicolas Bonnefon std::mutex* list_mutex ); 77b0345991SNicolas Bonnefon void interruptWait(); 78b278d183SNicolas Bonnefon 79b278d183SNicolas Bonnefon private: 80b278d183SNicolas Bonnefon // Only written at initialisation so no protection needed. 81b278d183SNicolas Bonnefon const int inotify_fd_; 82b278d183SNicolas Bonnefon 83b0345991SNicolas Bonnefon // Breaking pipe 84b0345991SNicolas Bonnefon int breaking_pipe_read_fd_; 85b0345991SNicolas Bonnefon int breaking_pipe_write_fd_; 86b0345991SNicolas Bonnefon 87b278d183SNicolas Bonnefon // Private member functions 88b278d183SNicolas Bonnefon size_t processINotifyEvent( const struct inotify_event* event, 89f09fa651SNicolas Bonnefon INotifyObservedFileList* list, 90b278d183SNicolas Bonnefon std::mutex* list_mutex, 91f09fa651SNicolas Bonnefon std::vector<INotifyObservedFile*>* files_to_notify ); 92c540156cSNicolas Bonnefon }; 93c540156cSNicolas Bonnefon 94c540156cSNicolas Bonnefon #endif 95