xref: /glogg/src/inotifywatchtowerdriver.h (revision 4fc8b18a21bd30bff0e4e47756c46ed70894d2ee)
19ebe83d5SNicolas Bonnefon /*
29ebe83d5SNicolas Bonnefon  * Copyright (C) 2015 Nicolas Bonnefon and other contributors
39ebe83d5SNicolas Bonnefon  *
49ebe83d5SNicolas Bonnefon  * This file is part of glogg.
59ebe83d5SNicolas Bonnefon  *
69ebe83d5SNicolas Bonnefon  * glogg is free software: you can redistribute it and/or modify
79ebe83d5SNicolas Bonnefon  * it under the terms of the GNU General Public License as published by
89ebe83d5SNicolas Bonnefon  * the Free Software Foundation, either version 3 of the License, or
99ebe83d5SNicolas Bonnefon  * (at your option) any later version.
109ebe83d5SNicolas Bonnefon  *
119ebe83d5SNicolas Bonnefon  * glogg is distributed in the hope that it will be useful,
129ebe83d5SNicolas Bonnefon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
139ebe83d5SNicolas Bonnefon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
149ebe83d5SNicolas Bonnefon  * GNU General Public License for more details.
159ebe83d5SNicolas Bonnefon  *
169ebe83d5SNicolas Bonnefon  * You should have received a copy of the GNU General Public License
179ebe83d5SNicolas Bonnefon  * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
189ebe83d5SNicolas Bonnefon  */
199ebe83d5SNicolas Bonnefon 
20c540156cSNicolas Bonnefon #ifndef INOTIFYWATCHTOWERDRIVER_H
21c540156cSNicolas Bonnefon #define INOTIFYWATCHTOWERDRIVER_H
22c540156cSNicolas Bonnefon 
23b278d183SNicolas Bonnefon #include <memory>
24b278d183SNicolas Bonnefon #include <mutex>
25b278d183SNicolas Bonnefon #include <vector>
26c540156cSNicolas Bonnefon 
27f09fa651SNicolas Bonnefon template <typename Driver>
28b278d183SNicolas Bonnefon class ObservedFile;
29f09fa651SNicolas Bonnefon template <typename Driver>
30b278d183SNicolas Bonnefon class ObservedFileList;
31b278d183SNicolas Bonnefon 
32b278d183SNicolas Bonnefon class INotifyWatchTowerDriver {
33c540156cSNicolas Bonnefon   public:
34b278d183SNicolas Bonnefon     class FileId {
35b278d183SNicolas Bonnefon       public:
36b278d183SNicolas Bonnefon         friend class INotifyWatchTowerDriver;
37b278d183SNicolas Bonnefon 
FileId()38dc7f5916SNicolas Bonnefon         FileId() { wd_ = -1; }
39b278d183SNicolas Bonnefon         bool operator==( const FileId& other ) const
40b278d183SNicolas Bonnefon         { return wd_ == other.wd_; }
41b278d183SNicolas Bonnefon       private:
FileId(int wd)42b278d183SNicolas Bonnefon         FileId( int wd ) { wd_ = wd; }
43dc7f5916SNicolas Bonnefon         int wd_;
44c540156cSNicolas Bonnefon     };
45b278d183SNicolas Bonnefon     class DirId {
46b278d183SNicolas Bonnefon       public:
47b278d183SNicolas Bonnefon         friend class INotifyWatchTowerDriver;
48b278d183SNicolas Bonnefon 
DirId()49dc7f5916SNicolas Bonnefon         DirId() { wd_ = -1; }
50b278d183SNicolas Bonnefon         bool operator==( const DirId& other ) const
51b278d183SNicolas Bonnefon         { return wd_ == other.wd_; }
valid()528b11848fSNicolas Bonnefon         bool valid() const
538b11848fSNicolas Bonnefon         { return (wd_ != -1); }
54b278d183SNicolas Bonnefon       private:
DirId(int wd)55b278d183SNicolas Bonnefon         DirId( int wd ) { wd_ = wd; }
56dc7f5916SNicolas Bonnefon         int wd_;
57c540156cSNicolas Bonnefon     };
58b278d183SNicolas Bonnefon     class SymlinkId {
59b278d183SNicolas Bonnefon       public:
60b278d183SNicolas Bonnefon         friend class INotifyWatchTowerDriver;
61b278d183SNicolas Bonnefon 
SymlinkId()62dc7f5916SNicolas Bonnefon         SymlinkId() { wd_ = -1; }
63b278d183SNicolas Bonnefon         bool operator==( const SymlinkId& other ) const
64b278d183SNicolas Bonnefon         { return wd_ == other.wd_; }
65b278d183SNicolas Bonnefon       private:
SymlinkId(int wd)66b278d183SNicolas Bonnefon         SymlinkId( int wd ) { wd_ = wd; }
67dc7f5916SNicolas Bonnefon         int wd_;
68c540156cSNicolas Bonnefon     };
69c540156cSNicolas Bonnefon 
70*4fc8b18aSNicolas Bonnefon     // Dummy class for inotify
71*4fc8b18aSNicolas Bonnefon     class FileChangeToken {
72*4fc8b18aSNicolas Bonnefon       public:
FileChangeToken()73*4fc8b18aSNicolas Bonnefon         FileChangeToken() {}
FileChangeToken(const std::string &)74*4fc8b18aSNicolas Bonnefon         FileChangeToken( const std::string& ) {}
75*4fc8b18aSNicolas Bonnefon 
readFromFile(const std::string &)76*4fc8b18aSNicolas Bonnefon         void readFromFile( const std::string& ) {}
77*4fc8b18aSNicolas Bonnefon 
78*4fc8b18aSNicolas Bonnefon         bool operator!=( const FileChangeToken& )
79*4fc8b18aSNicolas Bonnefon         { return true; }
80*4fc8b18aSNicolas Bonnefon     };
81*4fc8b18aSNicolas Bonnefon 
8258f443c7SNicolas Bonnefon #ifdef HAS_TEMPLATE_ALIASES
83f09fa651SNicolas Bonnefon     using INotifyObservedFile = ObservedFile<INotifyWatchTowerDriver>;
84f09fa651SNicolas Bonnefon     using INotifyObservedFileList = ObservedFileList<INotifyWatchTowerDriver>;
8558f443c7SNicolas Bonnefon #else
8658f443c7SNicolas Bonnefon     typedef ObservedFile<INotifyWatchTowerDriver> INotifyObservedFile;
8758f443c7SNicolas Bonnefon     typedef ObservedFileList<INotifyWatchTowerDriver> INotifyObservedFileList;
8858f443c7SNicolas Bonnefon #endif
89f09fa651SNicolas Bonnefon 
90f09fa651SNicolas Bonnefon     // Default constructor
91c540156cSNicolas Bonnefon     INotifyWatchTowerDriver();
92b0345991SNicolas Bonnefon     ~INotifyWatchTowerDriver();
93b0345991SNicolas Bonnefon 
94b0345991SNicolas Bonnefon     // No copy/assign/move please
95b0345991SNicolas Bonnefon     INotifyWatchTowerDriver( const INotifyWatchTowerDriver& ) = delete;
96b0345991SNicolas Bonnefon     INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver& ) = delete;
97b0345991SNicolas Bonnefon     INotifyWatchTowerDriver( const INotifyWatchTowerDriver&& ) = delete;
98b0345991SNicolas Bonnefon     INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver&& ) = delete;
99c540156cSNicolas Bonnefon 
100b278d183SNicolas Bonnefon     FileId addFile( const std::string& file_name );
101b278d183SNicolas Bonnefon     SymlinkId addSymlink( const std::string& file_name );
102b278d183SNicolas Bonnefon     DirId addDir( const std::string& file_name );
103c540156cSNicolas Bonnefon 
104b278d183SNicolas Bonnefon     void removeFile( const FileId& file_id );
105b278d183SNicolas Bonnefon     void removeSymlink( const SymlinkId& symlink_id );
1063104b268SNicolas Bonnefon     void removeDir( const DirId& dir_id );
107c540156cSNicolas Bonnefon 
1083104b268SNicolas Bonnefon     // Wait for an event for the OS, treat it and
1093104b268SNicolas Bonnefon     // return a list of files to notify about.
1103104b268SNicolas Bonnefon     // This must be called with the lock on the list held,
1113104b268SNicolas Bonnefon     // the function will unlock it temporary whilst blocking.
11291f7c705SNicolas Bonnefon     // Also returns a list of file that need readding
11391f7c705SNicolas Bonnefon     // (because of renames/symlink...)
114f09fa651SNicolas Bonnefon     std::vector<INotifyObservedFile*> waitAndProcessEvents(
115f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
11691f7c705SNicolas Bonnefon             std::unique_lock<std::mutex>* list_mutex,
117*4fc8b18aSNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding,
118*4fc8b18aSNicolas Bonnefon             int timeout_ms );
1193104b268SNicolas Bonnefon 
1203104b268SNicolas Bonnefon     // Interrupt waitAndProcessEvents if it is blocking.
121b0345991SNicolas Bonnefon     void interruptWait();
122b278d183SNicolas Bonnefon 
123b278d183SNicolas Bonnefon   private:
124b278d183SNicolas Bonnefon     // Only written at initialisation so no protection needed.
125b278d183SNicolas Bonnefon     const int inotify_fd_;
126b278d183SNicolas Bonnefon 
127b0345991SNicolas Bonnefon     // Breaking pipe
128b0345991SNicolas Bonnefon     int breaking_pipe_read_fd_;
129b0345991SNicolas Bonnefon     int breaking_pipe_write_fd_;
130b0345991SNicolas Bonnefon 
131b278d183SNicolas Bonnefon     // Private member functions
132b278d183SNicolas Bonnefon     size_t processINotifyEvent( const struct inotify_event* event,
133f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
13491f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_to_notify,
13591f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding );
136c540156cSNicolas Bonnefon };
137c540156cSNicolas Bonnefon 
138c540156cSNicolas Bonnefon #endif
139