OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/directory_watcher.h" | 5 #include "base/directory_watcher.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <sys/ioctl.h> | 9 #include <sys/ioctl.h> |
10 #include <sys/inotify.h> | 10 #include <sys/inotify.h> |
11 #include <sys/select.h> | 11 #include <sys/select.h> |
12 #include <unistd.h> | 12 #include <unistd.h> |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
15 #include <set> | 15 #include <set> |
16 #include <utility> | 16 #include <utility> |
17 #include <vector> | 17 #include <vector> |
18 | 18 |
| 19 #include "base/eintr_wrappers.h" |
19 #include "base/file_path.h" | 20 #include "base/file_path.h" |
20 #include "base/hash_tables.h" | 21 #include "base/hash_tables.h" |
21 #include "base/lock.h" | 22 #include "base/lock.h" |
22 #include "base/logging.h" | 23 #include "base/logging.h" |
23 #include "base/message_loop.h" | 24 #include "base/message_loop.h" |
24 #include "base/scoped_ptr.h" | 25 #include "base/scoped_ptr.h" |
25 #include "base/singleton.h" | 26 #include "base/singleton.h" |
26 #include "base/task.h" | 27 #include "base/task.h" |
27 #include "base/thread.h" | 28 #include "base/thread.h" |
28 | 29 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 } | 94 } |
94 | 95 |
95 virtual void Run() { | 96 virtual void Run() { |
96 while (true) { | 97 while (true) { |
97 fd_set rfds; | 98 fd_set rfds; |
98 FD_ZERO(&rfds); | 99 FD_ZERO(&rfds); |
99 FD_SET(inotify_fd_, &rfds); | 100 FD_SET(inotify_fd_, &rfds); |
100 FD_SET(shutdown_fd_, &rfds); | 101 FD_SET(shutdown_fd_, &rfds); |
101 | 102 |
102 // Wait until some inotify events are available. | 103 // Wait until some inotify events are available. |
103 int select_result = select(std::max(inotify_fd_, shutdown_fd_) + 1, | 104 int select_result = |
104 &rfds, NULL, NULL, NULL); | 105 HANDLE_EINTR(select(std::max(inotify_fd_, shutdown_fd_) + 1, |
| 106 &rfds, NULL, NULL, NULL)); |
105 if (select_result < 0) { | 107 if (select_result < 0) { |
106 if (errno == EINTR) | |
107 continue; | |
108 DLOG(WARNING) << "select failed: " << strerror(errno); | 108 DLOG(WARNING) << "select failed: " << strerror(errno); |
109 return; | 109 return; |
110 } | 110 } |
111 | 111 |
112 if (FD_ISSET(shutdown_fd_, &rfds)) | 112 if (FD_ISSET(shutdown_fd_, &rfds)) |
113 return; | 113 return; |
114 | 114 |
115 // Adjust buffer size to current event queue size. | 115 // Adjust buffer size to current event queue size. |
116 int buffer_size; | 116 int buffer_size; |
117 int ioctl_result = ioctl(inotify_fd_, FIONREAD, &buffer_size); | 117 int ioctl_result = HANDLE_EINTR(ioctl(inotify_fd_, FIONREAD, |
| 118 &buffer_size)); |
118 | 119 |
119 if (ioctl_result != 0) { | 120 if (ioctl_result != 0) { |
120 DLOG(WARNING) << "ioctl failed: " << strerror(errno); | 121 DLOG(WARNING) << "ioctl failed: " << strerror(errno); |
121 return; | 122 return; |
122 } | 123 } |
123 | 124 |
124 std::vector<char> buffer(buffer_size); | 125 std::vector<char> buffer(buffer_size); |
125 | 126 |
126 ssize_t bytes_read; | 127 ssize_t bytes_read = HANDLE_EINTR(read(inotify_fd_, &buffer[0], |
127 do { | 128 buffer_size)); |
128 bytes_read = read(inotify_fd_, &buffer[0], buffer_size); | |
129 } while (bytes_read < 0 && errno == EINTR); | |
130 | 129 |
131 if (bytes_read < 0) { | 130 if (bytes_read < 0) { |
132 DLOG(WARNING) << "read from inotify fd failed: " << strerror(errno); | 131 DLOG(WARNING) << "read from inotify fd failed: " << strerror(errno); |
133 return; | 132 return; |
134 } | 133 } |
135 | 134 |
136 ssize_t i = 0; | 135 ssize_t i = 0; |
137 while (i < bytes_read) { | 136 while (i < bytes_read) { |
138 inotify_event* event = reinterpret_cast<inotify_event*>(&buffer[i]); | 137 inotify_event* event = reinterpret_cast<inotify_event*>(&buffer[i]); |
139 size_t event_size = sizeof(inotify_event) + event->len; | 138 size_t event_size = sizeof(inotify_event) + event->len; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 thread_.message_loop()->PostTask( | 180 thread_.message_loop()->PostTask( |
182 FROM_HERE, new InotifyReaderTask(this, inotify_fd_, shutdown_pipe_[0])); | 181 FROM_HERE, new InotifyReaderTask(this, inotify_fd_, shutdown_pipe_[0])); |
183 valid_ = true; | 182 valid_ = true; |
184 } | 183 } |
185 } | 184 } |
186 | 185 |
187 InotifyReader::~InotifyReader() { | 186 InotifyReader::~InotifyReader() { |
188 if (valid_) { | 187 if (valid_) { |
189 // Write to the self-pipe so that the select call in InotifyReaderTask | 188 // Write to the self-pipe so that the select call in InotifyReaderTask |
190 // returns. | 189 // returns. |
191 ssize_t bytes_written; | 190 ssize_t bytes_written = HANDLE_EINTR(write(shutdown_pipe_[1], "", 1)); |
192 do { | |
193 bytes_written = write(shutdown_pipe_[1], "", 1); | |
194 if (bytes_written == 0) | |
195 continue; | |
196 } while (bytes_written == -1 && errno == EINTR); | |
197 thread_.Stop(); | 191 thread_.Stop(); |
198 } | 192 } |
199 if (inotify_fd_ >= 0) | 193 if (inotify_fd_ >= 0) |
200 close(inotify_fd_); | 194 close(inotify_fd_); |
201 if (shutdown_pipe_[0] >= 0) | 195 if (shutdown_pipe_[0] >= 0) |
202 close(shutdown_pipe_[0]); | 196 close(shutdown_pipe_[0]); |
203 if (shutdown_pipe_[1] >= 0) | 197 if (shutdown_pipe_[1] >= 0) |
204 close(shutdown_pipe_[1]); | 198 close(shutdown_pipe_[1]); |
205 } | 199 } |
206 | 200 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 watch_ = Singleton<InotifyReader>::get()->AddWatch(path, delegate_); | 312 watch_ = Singleton<InotifyReader>::get()->AddWatch(path, delegate_); |
319 | 313 |
320 return watch_ != InotifyReader::kInvalidWatch; | 314 return watch_ != InotifyReader::kInvalidWatch; |
321 } | 315 } |
322 | 316 |
323 } // namespace | 317 } // namespace |
324 | 318 |
325 DirectoryWatcher::DirectoryWatcher() { | 319 DirectoryWatcher::DirectoryWatcher() { |
326 impl_ = new DirectoryWatcherImpl(); | 320 impl_ = new DirectoryWatcherImpl(); |
327 } | 321 } |
OLD | NEW |