| 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 |