xref: /glogg/src/inotifywatchtowerdriver.h (revision 3104b26858f76d3848af58b8865d4e7d5735d2f8)
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