Home | History | Annotate | Download | only in dns
      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 
      5 #include "net/dns/notify_watcher_mac.h"
      6 
      7 #include <notify.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/posix/eintr_wrapper.h"
     11 
     12 namespace net {
     13 
     14 NotifyWatcherMac::NotifyWatcherMac() : notify_fd_(-1), notify_token_(-1) {}
     15 
     16 NotifyWatcherMac::~NotifyWatcherMac() {
     17   Cancel();
     18 }
     19 
     20 bool NotifyWatcherMac::Watch(const char* key, const CallbackType& callback) {
     21   DCHECK(key);
     22   DCHECK(!callback.is_null());
     23   Cancel();
     24   uint32_t status = notify_register_file_descriptor(
     25       key, &notify_fd_, 0, &notify_token_);
     26   if (status != NOTIFY_STATUS_OK)
     27     return false;
     28   DCHECK_GE(notify_fd_, 0);
     29   if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
     30           notify_fd_,
     31           true,
     32           base::MessageLoopForIO::WATCH_READ,
     33           &watcher_,
     34           this)) {
     35     Cancel();
     36     return false;
     37   }
     38   callback_ = callback;
     39   return true;
     40 }
     41 
     42 void NotifyWatcherMac::Cancel() {
     43   if (notify_fd_ >= 0) {
     44     notify_cancel(notify_token_);  // Also closes |notify_fd_|.
     45     notify_fd_ = -1;
     46     callback_.Reset();
     47     watcher_.StopWatchingFileDescriptor();
     48   }
     49 }
     50 
     51 void NotifyWatcherMac::OnFileCanReadWithoutBlocking(int fd) {
     52   int token;
     53   int status = HANDLE_EINTR(read(notify_fd_, &token, sizeof(token)));
     54   if (status != sizeof(token)) {
     55     Cancel();
     56     callback_.Run(false);
     57     return;
     58   }
     59   // Ignoring |token| value to avoid possible endianness mismatch:
     60   // http://openradar.appspot.com/8821081
     61   callback_.Run(true);
     62 }
     63 
     64 }  // namespace net
     65