xref: /glogg/src/inotifywatchtowerdriver.h (revision 91f7c70525aef93239c2facfe440e65d1672a468)
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 
4958f443c7SNicolas Bonnefon #ifdef HAS_TEMPLATE_ALIASES
50f09fa651SNicolas Bonnefon     using INotifyObservedFile = ObservedFile<INotifyWatchTowerDriver>;
51f09fa651SNicolas Bonnefon     using INotifyObservedFileList = ObservedFileList<INotifyWatchTowerDriver>;
5258f443c7SNicolas Bonnefon #else
5358f443c7SNicolas Bonnefon     typedef ObservedFile<INotifyWatchTowerDriver> INotifyObservedFile;
5458f443c7SNicolas Bonnefon     typedef ObservedFileList<INotifyWatchTowerDriver> INotifyObservedFileList;
5558f443c7SNicolas 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 );
733104b268SNicolas Bonnefon     void removeDir( const DirId& dir_id );
74c540156cSNicolas Bonnefon 
753104b268SNicolas Bonnefon     // Wait for an event for the OS, treat it and
763104b268SNicolas Bonnefon     // return a list of files to notify about.
773104b268SNicolas Bonnefon     // This must be called with the lock on the list held,
783104b268SNicolas Bonnefon     // the function will unlock it temporary whilst blocking.
79*91f7c705SNicolas Bonnefon     // Also returns a list of file that need readding
80*91f7c705SNicolas Bonnefon     // (because of renames/symlink...)
81f09fa651SNicolas Bonnefon     std::vector<INotifyObservedFile*> waitAndProcessEvents(
82f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
83*91f7c705SNicolas Bonnefon             std::unique_lock<std::mutex>* list_mutex,
84*91f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding );
853104b268SNicolas Bonnefon 
863104b268SNicolas Bonnefon     // Interrupt waitAndProcessEvents if it is blocking.
87b0345991SNicolas Bonnefon     void interruptWait();
88b278d183SNicolas Bonnefon 
89b278d183SNicolas Bonnefon   private:
90b278d183SNicolas Bonnefon     // Only written at initialisation so no protection needed.
91b278d183SNicolas Bonnefon     const int inotify_fd_;
92b278d183SNicolas Bonnefon 
93b0345991SNicolas Bonnefon     // Breaking pipe
94b0345991SNicolas Bonnefon     int breaking_pipe_read_fd_;
95b0345991SNicolas Bonnefon     int breaking_pipe_write_fd_;
96b0345991SNicolas Bonnefon 
97b278d183SNicolas Bonnefon     // Private member functions
98b278d183SNicolas Bonnefon     size_t processINotifyEvent( const struct inotify_event* event,
99f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
100*91f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_to_notify,
101*91f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding );
102c540156cSNicolas Bonnefon };
103c540156cSNicolas Bonnefon 
104c540156cSNicolas Bonnefon #endif
105