CernVM-FS  2.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
file_watcher.cc
Go to the documentation of this file.
1 
5 #include "file_watcher.h"
6 
7 #include <unistd.h>
8 
9 #include <cassert>
10 
11 #include "backoff.h"
12 #include "logging.h"
13 #include "util/posix.h"
14 
15 namespace file_watcher {
16 
18 
20 
21 const unsigned FileWatcher::kInitialDelay = 1000;
22 const unsigned FileWatcher::kMaxDelay = 10000;
23 const unsigned FileWatcher::kResetDelay = 50000;
24 
26  : handler_map_()
27  , control_pipe_to_back_()
28  , control_pipe_to_front_()
29  , started_(false) {}
30 
32  Stop();
33 }
34 
35 void FileWatcher::RegisterHandler(const std::string& file_path,
36  EventHandler* handler) {
37  handler_map_[file_path] = handler;
38 }
39 
41  if (started_) {
42  return false;
43  }
44 
47 
48  assert(pthread_create(&thread_, NULL,
49  &FileWatcher::BackgroundThread, this) == 0);
50 
51  // Before returning, wait for a start signal in the control pipe
52  // from the background thread.
53  char buffer[1];
54  ReadHalfPipe(control_pipe_to_front_[0], buffer, 1);
55 
56  started_ = true;
57  return true;
58 }
59 
61  if (!started_) {
62  return;
63  }
64 
65  WritePipe(control_pipe_to_back_[1], "q", 1);
66  assert(pthread_join(thread_, NULL) == 0);
67 
70 
71  for (HandlerMap::iterator it = handler_map_.begin(); it != handler_map_.end();
72  ++it) {
73  delete it->second;
74  }
75 
76  started_ = false;
77 }
78 
80  FileWatcher* watcher = reinterpret_cast<FileWatcher*>(d);
81 
82  if (!watcher->RunEventLoop(watcher->handler_map_,
83  watcher->control_pipe_to_back_[0],
84  watcher->control_pipe_to_front_[1])) {
85  LogCvmfs(kLogCvmfs, kLogDebug, "Error running event loop.");
86  }
87 
88  pthread_exit(NULL);
89 }
90 
91 void FileWatcher::RegisterFilter(const std::string& file_path,
92  EventHandler* handler) {
93  bool done = false;
95  while (!done) {
96  int wd = TryRegisterFilter(file_path);
97  if (wd < 0) {
98  LogCvmfs(
100  "FileWatcher - Could not add watch for file %s. Retrying.",
101  file_path.c_str());
102  throttle.Throttle();
103  continue;
104  }
105 
106  watch_records_[wd] = WatchRecord(file_path, handler);
107 
108  done = true;
109  }
110  throttle.Reset();
111 }
112 
113 } // namespace file_watcher
void RegisterFilter(const std::string &file_path, EventHandler *handler)
Definition: file_watcher.cc:91
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
static const unsigned kMaxDelay
Definition: file_watcher.h:79
assert((mem||(size==0))&&"Out Of Memory")
static void * BackgroundThread(void *d)
Definition: file_watcher.cc:79
static const unsigned kResetDelay
Definition: file_watcher.h:80
virtual bool RunEventLoop(const HandlerMap &handler_map, int read_pipe, int write_pipe)=0
void MakePipe(int pipe_fd[2])
Definition: posix.cc:525
void Throttle()
Definition: backoff.cc:50
void ReadHalfPipe(int fd, void *buf, size_t nbyte)
Definition: posix.cc:558
static const unsigned kInitialDelay
Definition: file_watcher.h:78
void Reset()
Definition: backoff.cc:42
void RegisterHandler(const std::string &file_path, EventHandler *handler)
Definition: file_watcher.cc:35
std::map< int, WatchRecord > watch_records_
Definition: file_watcher.h:90
virtual int TryRegisterFilter(const std::string &file_path)=0
void WritePipe(int fd, const void *buf, size_t nbyte)
Definition: posix.cc:534
void ClosePipe(int pipe_fd[2])
Definition: posix.cc:584