xref: /glogg/src/inotifywatchtowerdriver.h (revision 9ebe83d51f785b947e84c5b8993afea9a272ffd5)
1*9ebe83d5SNicolas Bonnefon /*
2*9ebe83d5SNicolas Bonnefon  * Copyright (C) 2015 Nicolas Bonnefon and other contributors
3*9ebe83d5SNicolas Bonnefon  *
4*9ebe83d5SNicolas Bonnefon  * This file is part of glogg.
5*9ebe83d5SNicolas Bonnefon  *
6*9ebe83d5SNicolas Bonnefon  * glogg is free software: you can redistribute it and/or modify
7*9ebe83d5SNicolas Bonnefon  * it under the terms of the GNU General Public License as published by
8*9ebe83d5SNicolas Bonnefon  * the Free Software Foundation, either version 3 of the License, or
9*9ebe83d5SNicolas Bonnefon  * (at your option) any later version.
10*9ebe83d5SNicolas Bonnefon  *
11*9ebe83d5SNicolas Bonnefon  * glogg is distributed in the hope that it will be useful,
12*9ebe83d5SNicolas Bonnefon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*9ebe83d5SNicolas Bonnefon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*9ebe83d5SNicolas Bonnefon  * GNU General Public License for more details.
15*9ebe83d5SNicolas Bonnefon  *
16*9ebe83d5SNicolas Bonnefon  * You should have received a copy of the GNU General Public License
17*9ebe83d5SNicolas Bonnefon  * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
18*9ebe83d5SNicolas Bonnefon  */
19*9ebe83d5SNicolas 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 
38dc7f5916SNicolas Bonnefon         FileId() { wd_ = -1; }
39b278d183SNicolas Bonnefon         bool operator==( const FileId& other ) const
40b278d183SNicolas Bonnefon         { return wd_ == other.wd_; }
41b278d183SNicolas Bonnefon       private:
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 
49dc7f5916SNicolas Bonnefon         DirId() { wd_ = -1; }
50b278d183SNicolas Bonnefon         bool operator==( const DirId& other ) const
51b278d183SNicolas Bonnefon         { return wd_ == other.wd_; }
528b11848fSNicolas Bonnefon         bool valid() const
538b11848fSNicolas Bonnefon         { return (wd_ != -1); }
54b278d183SNicolas Bonnefon       private:
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 
62dc7f5916SNicolas Bonnefon         SymlinkId() { wd_ = -1; }
63b278d183SNicolas Bonnefon         bool operator==( const SymlinkId& other ) const
64b278d183SNicolas Bonnefon         { return wd_ == other.wd_; }
65b278d183SNicolas Bonnefon       private:
66b278d183SNicolas Bonnefon         SymlinkId( int wd ) { wd_ = wd; }
67dc7f5916SNicolas Bonnefon         int wd_;
68c540156cSNicolas Bonnefon     };
69c540156cSNicolas Bonnefon 
7058f443c7SNicolas Bonnefon #ifdef HAS_TEMPLATE_ALIASES
71f09fa651SNicolas Bonnefon     using INotifyObservedFile = ObservedFile<INotifyWatchTowerDriver>;
72f09fa651SNicolas Bonnefon     using INotifyObservedFileList = ObservedFileList<INotifyWatchTowerDriver>;
7358f443c7SNicolas Bonnefon #else
7458f443c7SNicolas Bonnefon     typedef ObservedFile<INotifyWatchTowerDriver> INotifyObservedFile;
7558f443c7SNicolas Bonnefon     typedef ObservedFileList<INotifyWatchTowerDriver> INotifyObservedFileList;
7658f443c7SNicolas Bonnefon #endif
77f09fa651SNicolas Bonnefon 
78f09fa651SNicolas Bonnefon     // Default constructor
79c540156cSNicolas Bonnefon     INotifyWatchTowerDriver();
80b0345991SNicolas Bonnefon     ~INotifyWatchTowerDriver();
81b0345991SNicolas Bonnefon 
82b0345991SNicolas Bonnefon     // No copy/assign/move please
83b0345991SNicolas Bonnefon     INotifyWatchTowerDriver( const INotifyWatchTowerDriver& ) = delete;
84b0345991SNicolas Bonnefon     INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver& ) = delete;
85b0345991SNicolas Bonnefon     INotifyWatchTowerDriver( const INotifyWatchTowerDriver&& ) = delete;
86b0345991SNicolas Bonnefon     INotifyWatchTowerDriver& operator=( const INotifyWatchTowerDriver&& ) = delete;
87c540156cSNicolas Bonnefon 
88b278d183SNicolas Bonnefon     FileId addFile( const std::string& file_name );
89b278d183SNicolas Bonnefon     SymlinkId addSymlink( const std::string& file_name );
90b278d183SNicolas Bonnefon     DirId addDir( const std::string& file_name );
91c540156cSNicolas Bonnefon 
92b278d183SNicolas Bonnefon     void removeFile( const FileId& file_id );
93b278d183SNicolas Bonnefon     void removeSymlink( const SymlinkId& symlink_id );
943104b268SNicolas Bonnefon     void removeDir( const DirId& dir_id );
95c540156cSNicolas Bonnefon 
963104b268SNicolas Bonnefon     // Wait for an event for the OS, treat it and
973104b268SNicolas Bonnefon     // return a list of files to notify about.
983104b268SNicolas Bonnefon     // This must be called with the lock on the list held,
993104b268SNicolas Bonnefon     // the function will unlock it temporary whilst blocking.
10091f7c705SNicolas Bonnefon     // Also returns a list of file that need readding
10191f7c705SNicolas Bonnefon     // (because of renames/symlink...)
102f09fa651SNicolas Bonnefon     std::vector<INotifyObservedFile*> waitAndProcessEvents(
103f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
10491f7c705SNicolas Bonnefon             std::unique_lock<std::mutex>* list_mutex,
10591f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding );
1063104b268SNicolas Bonnefon 
1073104b268SNicolas Bonnefon     // Interrupt waitAndProcessEvents if it is blocking.
108b0345991SNicolas Bonnefon     void interruptWait();
109b278d183SNicolas Bonnefon 
110b278d183SNicolas Bonnefon   private:
111b278d183SNicolas Bonnefon     // Only written at initialisation so no protection needed.
112b278d183SNicolas Bonnefon     const int inotify_fd_;
113b278d183SNicolas Bonnefon 
114b0345991SNicolas Bonnefon     // Breaking pipe
115b0345991SNicolas Bonnefon     int breaking_pipe_read_fd_;
116b0345991SNicolas Bonnefon     int breaking_pipe_write_fd_;
117b0345991SNicolas Bonnefon 
118b278d183SNicolas Bonnefon     // Private member functions
119b278d183SNicolas Bonnefon     size_t processINotifyEvent( const struct inotify_event* event,
120f09fa651SNicolas Bonnefon             INotifyObservedFileList* list,
12191f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_to_notify,
12291f7c705SNicolas Bonnefon             std::vector<INotifyObservedFile*>* files_needing_readding );
123c540156cSNicolas Bonnefon };
124c540156cSNicolas Bonnefon 
125c540156cSNicolas Bonnefon #endif
126