xref: /glogg/src/inotifywatchtowerdriver.h (revision 91f7c70525aef93239c2facfe440e65d1672a468)
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     // Also returns a list of file that need readding
80     // (because of renames/symlink...)
81     std::vector<INotifyObservedFile*> waitAndProcessEvents(
82             INotifyObservedFileList* list,
83             std::unique_lock<std::mutex>* list_mutex,
84             std::vector<INotifyObservedFile*>* files_needing_readding );
85 
86     // Interrupt waitAndProcessEvents if it is blocking.
87     void interruptWait();
88 
89   private:
90     // Only written at initialisation so no protection needed.
91     const int inotify_fd_;
92 
93     // Breaking pipe
94     int breaking_pipe_read_fd_;
95     int breaking_pipe_write_fd_;
96 
97     // Private member functions
98     size_t processINotifyEvent( const struct inotify_event* event,
99             INotifyObservedFileList* list,
100             std::vector<INotifyObservedFile*>* files_to_notify,
101             std::vector<INotifyObservedFile*>* files_needing_readding );
102 };
103 
104 #endif
105