12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/message_loop/message_pump_io_ios.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base { 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessagePumpIOSForIO::FileDescriptorWatcher::FileDescriptorWatcher() 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : is_persistent_(false), 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fdref_(NULL), 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_types_(0), 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd_source_(NULL), 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) watcher_(NULL) { 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessagePumpIOSForIO::FileDescriptorWatcher::~FileDescriptorWatcher() { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopWatchingFileDescriptor(); 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MessagePumpIOSForIO::FileDescriptorWatcher::StopWatchingFileDescriptor() { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fdref_ == NULL) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorDisableCallBacks(fdref_, callback_types_); 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (pump_) 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pump_->RemoveRunLoopSource(fd_source_); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd_source_.reset(); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fdref_.reset(); 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_types_ = 0; 31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pump_.reset(); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) watcher_ = NULL; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::FileDescriptorWatcher::Init( 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorRef fdref, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFOptionFlags callback_types, 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFRunLoopSourceRef fd_source, 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_persistent) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(fdref); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!fdref_); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_persistent_ = is_persistent; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fdref_.reset(fdref); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_types_ = callback_types; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fd_source_.reset(fd_source); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::FileDescriptorWatcher::OnFileCanReadWithoutBlocking( 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessagePumpIOSForIO* pump) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(callback_types_ & kCFFileDescriptorReadCallBack); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pump->WillProcessIOEvent(); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) watcher_->OnFileCanReadWithoutBlocking(fd); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pump->DidProcessIOEvent(); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::FileDescriptorWatcher::OnFileCanWriteWithoutBlocking( 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessagePumpIOSForIO* pump) { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(callback_types_ & kCFFileDescriptorWriteCallBack); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pump->WillProcessIOEvent(); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) watcher_->OnFileCanWriteWithoutBlocking(fd); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pump->DidProcessIOEvent(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochMessagePumpIOSForIO::MessagePumpIOSForIO() : weak_factory_(this) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessagePumpIOSForIO::~MessagePumpIOSForIO() { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MessagePumpIOSForIO::WatchFileDescriptor( 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool persistent, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int mode, 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileDescriptorWatcher *controller, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Watcher *delegate) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(fd, 0); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(controller); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(delegate); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(mode == WATCH_READ || mode == WATCH_WRITE || mode == WATCH_READ_WRITE); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WatchFileDescriptor should be called on the pump thread. It is not 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // threadsafe, and your watcher may never be registered. 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(watch_file_descriptor_caller_checker_.CalledOnValidThread()); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorContext source_context = {0}; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source_context.info = controller; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFOptionFlags callback_types = 0; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mode & WATCH_READ) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_types |= kCFFileDescriptorReadCallBack; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mode & WATCH_WRITE) { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_types |= kCFFileDescriptorWriteCallBack; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorRef fdref = controller->fdref_; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fdref == NULL) { 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFFileDescriptorRef> scoped_fdref( 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CFFileDescriptorCreate( 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kCFAllocatorDefault, fd, false, HandleFdIOEvent, &source_context)); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (scoped_fdref == NULL) { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "CFFileDescriptorCreate failed"; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorEnableCallBacks(scoped_fdref, callback_types); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(wtc): what should the 'order' argument be? 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFRunLoopSourceRef> scoped_fd_source( 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CFFileDescriptorCreateRunLoopSource( 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kCFAllocatorDefault, scoped_fdref, 0)); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (scoped_fd_source == NULL) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "CFFileDescriptorCreateRunLoopSource failed"; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFRunLoopAddSource(run_loop(), scoped_fd_source, kCFRunLoopCommonModes); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Transfer ownership of scoped_fdref and fd_source to controller. 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller->Init(scoped_fdref.release(), callback_types, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_fd_source.release(), persistent); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It's illegal to use this function to listen on 2 separate fds with the 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // same |controller|. 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (CFFileDescriptorGetNativeDescriptor(fdref) != fd) { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "FDs don't match: " 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << CFFileDescriptorGetNativeDescriptor(fdref) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " != " << fd; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (persistent != controller->is_persistent_) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "persistent doesn't match"; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Combine old/new event masks. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorDisableCallBacks(fdref, controller->callback_types_); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller->callback_types_ |= callback_types; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorEnableCallBacks(fdref, controller->callback_types_); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller->set_watcher(delegate); 146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch controller->set_pump(weak_factory_.GetWeakPtr()); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::RemoveRunLoopSource(CFRunLoopSourceRef source) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFRunLoopRemoveSource(run_loop(), source, kCFRunLoopCommonModes); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::AddIOObserver(IOObserver *obs) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_observers_.AddObserver(obs); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::RemoveIOObserver(IOObserver *obs) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_observers_.RemoveObserver(obs); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::WillProcessIOEvent() { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(IOObserver, io_observers_, WillProcessIOEvent()); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::DidProcessIOEvent() { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(IOObserver, io_observers_, DidProcessIOEvent()); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessagePumpIOSForIO::HandleFdIOEvent(CFFileDescriptorRef fdref, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFOptionFlags callback_types, 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* context) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileDescriptorWatcher* controller = 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<FileDescriptorWatcher*>(context); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(fdref, controller->fdref_); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure that |fdref| will remain live for the duration of this function 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // call even if |controller| is deleted or |StopWatchingFileDescriptor()| is 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // called, either of which will cause |fdref| to be released. 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ScopedCFTypeRef<CFFileDescriptorRef> scoped_fdref( 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fdref, base::scoped_policy::RETAIN); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd = CFFileDescriptorGetNativeDescriptor(fdref); 186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MessagePumpIOSForIO* pump = controller->pump().get(); 187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(pump); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (callback_types & kCFFileDescriptorWriteCallBack) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller->OnFileCanWriteWithoutBlocking(fd, pump); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Perform the read callback only if the file descriptor has not been 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // invalidated in the write callback. As |FileDescriptorWatcher| invalidates 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its file descriptor on destruction, the file descriptor being valid also 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // guarantees that |controller| has not been deleted. 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (callback_types & kCFFileDescriptorReadCallBack && 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorIsValid(fdref)) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(fdref, controller->fdref_); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller->OnFileCanReadWithoutBlocking(fd, pump); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Re-enable callbacks after the read/write if the file descriptor is still 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // valid and the controller is persistent. 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (CFFileDescriptorIsValid(fdref) && controller->is_persistent_) { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(fdref, controller->fdref_); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CFFileDescriptorEnableCallBacks(fdref, callback_types); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace base 210