xref: /glogg/src/inotifywatchtowerdriver.h (revision 8b11848fd9995077713535870cee0df00a8eeea0)
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_; }
33*8b11848fSNicolas Bonnefon         bool valid() const
34*8b11848fSNicolas Bonnefon         { return (wd_ != -1); }
35b278d183SNicolas Bonnefon       private:
36b278d183SNicolas Bonnefon         DirId( int wd ) { wd_ = wd; }
37dc7f5916SNicolas Bonnefon         int wd_;
38c540156cSNicolas Bonnefon     };
39b278d183SNicolas Bonnefon     class SymlinkId {
40b278d183SNicolas Bonnefon       public:
41b278d183SNicolas Bonnefon         friend class INotifyWatchTowerDriver;
42b278d183SNicolas Bonnefon 
43dc7f5916SNicolas Bonnefon         SymlinkId() { wd_ = -1; }
44b278d183SNicolas Bonnefon         bool operator==( const SymlinkId& other ) const
45b278d183SNicolas Bonnefon         { return wd_ == other.wd_; }
46b278d183SNicolas Bonnefon       private:
47b278d183SNicolas Bonnefon         SymlinkId( int wd ) { wd_ = wd; }
48dc7f5916SNicolas Bonnefon         int wd_;
49c540156cSNicolas Bonnefon     };
50c540156cSNicolas Bonnefon 
5158f443c7SNicolas Bonnefon #ifdef HAS_TEMPLATE_ALIASES
52f09fa651SNicolas Bonnefon     using INotifyObservedFile = ObservedFile<INotifyWatchTowerDriver>;
53f09fa651SNicolas Bonnefon     using INotifyObservedFileList = ObservedFileList<INotifyWatchTowerDriver>;
5458f443c7SNicolas Bonnefon #else
5558f443c7SNicolas Bonnefon     typedef ObservedFile<INotifyWatchTowerDriver> INotifyObservedFile;
5658f443c7SNicolas Bonnefon     typedef ObservedFileList<INotifyWatchTowerDriver> INotifyObservedFileList;
5758f443c7SNicolas Bonnefon #endif
58f09fa651SNicolas Bonnefon 
59f09fa651SNicolas Bonnefon     // Default constructor
60c540156cSNicolas Bonnefon     INotifyWatchTowerDriver();
61b0345991SNicolas Bonnefon     ~INotifyWatchTowerDriver();
62b0345991SNicolas Bonnefon 
63b0345991SNicolas Bonnefon     // No copy/assign/move please
64b0345991SNicolas Bonnefon     INotifyWatchTowerDriver( const INotifyWatchTowerDriver& ) = delete;
65b0345991SNicolas Bonnefon     INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver& ) = delete;
66b0345991SNicolas Bonnefon     INotifyWatchTowerDriver( const INotifyWatchTowerDriver&& ) = delete;
67b0345991SNicolas Bonnefon     INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver&& ) = delete;
68c540156cSNicolas Bonnefon 
69b278d183SNicolas Bonnefon     FileId addFile( const std::string& file_name );
70b278d183SNicolas Bonnefon     SymlinkId addSymlink( const std::string& file_name );
71b278d183SNicolas Bonnefon     DirId addDir( const std::string& file_name );
72c540156cSNicolas Bonnefon 
73b278d183SNicolas Bonnefon     void removeFile( const FileId& file_id );
74b278d183SNicolas Bonnefon     void removeSymlink( const SymlinkId& symlink_id );
753104b268SNicolas Bonnefon     void removeDir( const DirId& dir_id );
76c540156cSNicolas Bonnefon 
773104b268SNicolas Bonnefon     // Wait for an event for the OS, treat it and
783104b268SNicolas Bonnefon     // return a list of files to notify about.
793104b268SNicolas Bonnefon     // This must be called with the lock on the list held,
803104b268SNicolas Bonnefon     // the function will unlock it temporary whilst blocking.
8191f7c705SNicolas Bonnefon     // Also returns a list of file that need readding
8291f7c705SNicolas Bonnefon     // (because of renames/symlink...)
83f09fa651SNicolas Bonnefon     std::vector<INotifyObservedFile*> waitAndProcessEvents(
84f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
8591f7c705SNicolas Bonnefon             std::unique_lock<std::mutex>* list_mutex,
8691f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding );
873104b268SNicolas Bonnefon 
883104b268SNicolas Bonnefon     // Interrupt waitAndProcessEvents if it is blocking.
89b0345991SNicolas Bonnefon     void interruptWait();
90b278d183SNicolas Bonnefon 
91b278d183SNicolas Bonnefon   private:
92b278d183SNicolas Bonnefon     // Only written at initialisation so no protection needed.
93b278d183SNicolas Bonnefon     const int inotify_fd_;
94b278d183SNicolas Bonnefon 
95b0345991SNicolas Bonnefon     // Breaking pipe
96b0345991SNicolas Bonnefon     int breaking_pipe_read_fd_;
97b0345991SNicolas Bonnefon     int breaking_pipe_write_fd_;
98b0345991SNicolas Bonnefon 
99b278d183SNicolas Bonnefon     // Private member functions
100b278d183SNicolas Bonnefon     size_t processINotifyEvent( const struct inotify_event* event,
101f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
10291f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_to_notify,
10391f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding );
104c540156cSNicolas Bonnefon };
105c540156cSNicolas Bonnefon 
106c540156cSNicolas Bonnefon #endif
107