xref: /glogg/src/inotifywatchtowerdriver.h (revision 3104b26858f76d3848af58b8865d4e7d5735d2f8)
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 );
73*3104b268SNicolas Bonnefon     void removeDir( const DirId& dir_id );
74c540156cSNicolas Bonnefon 
75*3104b268SNicolas Bonnefon     // Wait for an event for the OS, treat it and
76*3104b268SNicolas Bonnefon     // return a list of files to notify about.
77*3104b268SNicolas Bonnefon     // This must be called with the lock on the list held,
78*3104b268SNicolas Bonnefon     // the function will unlock it temporary whilst blocking.
79f09fa651SNicolas Bonnefon     std::vector<INotifyObservedFile*> waitAndProcessEvents(
80f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
81*3104b268SNicolas Bonnefon             std::unique_lock<std::mutex>* list_mutex );
82*3104b268SNicolas Bonnefon 
83*3104b268SNicolas Bonnefon     // Interrupt waitAndProcessEvents if it is blocking.
84b0345991SNicolas Bonnefon     void interruptWait();
85b278d183SNicolas Bonnefon 
86b278d183SNicolas Bonnefon   private:
87b278d183SNicolas Bonnefon     // Only written at initialisation so no protection needed.
88b278d183SNicolas Bonnefon     const int inotify_fd_;
89b278d183SNicolas Bonnefon 
90b0345991SNicolas Bonnefon     // Breaking pipe
91b0345991SNicolas Bonnefon     int breaking_pipe_read_fd_;
92b0345991SNicolas Bonnefon     int breaking_pipe_write_fd_;
93b0345991SNicolas Bonnefon 
94b278d183SNicolas Bonnefon     // Private member functions
95b278d183SNicolas Bonnefon     size_t processINotifyEvent( const struct inotify_event* event,
96f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
97f09fa651SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_to_notify );
98c540156cSNicolas Bonnefon };
99c540156cSNicolas Bonnefon 
100c540156cSNicolas Bonnefon #endif
101