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