notify_watcher_mac.cc 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/dns/notify_watcher_mac.h"
  5. #include <notify.h>
  6. #include "base/bind.h"
  7. #include "base/check_op.h"
  8. #include "base/mac/mac_util.h"
  9. #include "base/posix/eintr_wrapper.h"
  10. namespace net {
  11. NotifyWatcherMac::NotifyWatcherMac() : notify_fd_(-1), notify_token_(-1) {}
  12. NotifyWatcherMac::~NotifyWatcherMac() {
  13. Cancel();
  14. }
  15. bool NotifyWatcherMac::Watch(const char* key, const CallbackType& callback) {
  16. DCHECK(key);
  17. DCHECK(!callback.is_null());
  18. Cancel();
  19. uint32_t status = notify_register_file_descriptor(
  20. key, &notify_fd_, 0, &notify_token_);
  21. if (status != NOTIFY_STATUS_OK)
  22. return false;
  23. DCHECK_GE(notify_fd_, 0);
  24. watcher_ = base::FileDescriptorWatcher::WatchReadable(
  25. notify_fd_,
  26. base::BindRepeating(&NotifyWatcherMac::OnFileCanReadWithoutBlocking,
  27. base::Unretained(this)));
  28. callback_ = callback;
  29. return true;
  30. }
  31. void NotifyWatcherMac::Cancel() {
  32. if (notify_fd_ >= 0) {
  33. watcher_.reset();
  34. notify_cancel(notify_token_); // Also closes |notify_fd_|.
  35. notify_fd_ = -1;
  36. callback_.Reset();
  37. }
  38. }
  39. void NotifyWatcherMac::OnFileCanReadWithoutBlocking() {
  40. int token;
  41. int status = HANDLE_EINTR(read(notify_fd_, &token, sizeof(token)));
  42. if (status != sizeof(token)) {
  43. Cancel();
  44. callback_.Run(false);
  45. return;
  46. }
  47. // Ignoring |token| value to avoid possible endianness mismatch:
  48. // http://openradar.appspot.com/8821081
  49. callback_.Run(true);
  50. }
  51. } // namespace net