15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/tcp_server_socket_libevent.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netdb.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netinet/in.h> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_net_log_params.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/tcp_client_socket.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kInvalidSocket = -1; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPServerSocketLibevent::TCPServerSocketLibevent( 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog* net_log, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::NetLog::Source& source) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : socket_(kInvalidSocket), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_socket_(NULL), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source.ToEventParametersCallback()); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TCPServerSocketLibevent::~TCPServerSocketLibevent() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket_ != kInvalidSocket) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TCPServerSocketLibevent::Listen(const IPEndPoint& address, int backlog) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(backlog, 0); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(socket_, kInvalidSocket); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) socket_ = socket(address.GetSockAddrFamily(), SOCK_STREAM, IPPROTO_TCP); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket_ < 0) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "socket() returned an error"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MapSystemError(errno); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SetNonBlocking(socket_)) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = MapSystemError(errno); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = SetSocketOptions(); 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (result != OK) { 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Close(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SockaddrStorage storage; 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!address.ToSockAddr(storage.addr, &storage.addr_len)) { 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Close(); 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return ERR_ADDRESS_INVALID; 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = bind(socket_, storage.addr, storage.addr_len); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "bind() returned an error"; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = MapSystemError(errno); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = listen(socket_, backlog); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "listen() returned an error"; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = MapSystemError(errno); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TCPServerSocketLibevent::GetLocalAddress(IPEndPoint* address) const { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(address); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SockaddrStorage storage; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (getsockname(socket_, storage.addr, &storage.addr_len) < 0) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MapSystemError(errno); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!address->FromSockAddr(storage.addr, storage.addr_len)) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_FAILED; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TCPServerSocketLibevent::Accept( 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<StreamSocket>* socket, const CompletionCallback& callback) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(socket); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(accept_callback_.is_null()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.BeginEvent(NetLog::TYPE_TCP_ACCEPT); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = AcceptInternal(socket); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_IO_PENDING) { 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) socket_, true, base::MessageLoopForIO::WATCH_READ, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &accept_socket_watcher_, this)) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "WatchFileDescriptor failed on read"; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MapSystemError(errno); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_socket_ = socket; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_callback_ = callback; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TCPServerSocketLibevent::SetSocketOptions() { 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // SO_REUSEADDR is useful for server sockets to bind to a recently unbound 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // port. When a socket is closed, the end point changes its state to TIME_WAIT 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // and wait for 2 MSL (maximum segment lifetime) to ensure the remote peer 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // acknowledges its closure. For server sockets, it is usually safe to 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // bind to a TIME_WAIT end point immediately, which is a widely adopted 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // behavior. 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Note that on *nix, SO_REUSEADDR does not enable the TCP socket to bind to 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // an end point that is already bound by another socket. To do that one must 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // set SO_REUSEPORT instead. This option is not provided on Linux prior 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to 3.9. 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // SO_REUSEPORT is provided in MacOS X and iOS. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int true_value = 1; 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &true_value, 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizeof(true_value)); 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (rv < 0) 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return MapSystemError(errno); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TCPServerSocketLibevent::AcceptInternal( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<StreamSocket>* socket) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SockaddrStorage storage; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int new_socket = HANDLE_EINTR(accept(socket_, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage.addr, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &storage.addr_len)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_socket < 0) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int net_error = MapSystemError(errno); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_error != ERR_IO_PENDING) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, net_error); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_error; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPEndPoint address; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!address.FromSockAddr(storage.addr, storage.addr_len)) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HANDLE_EINTR(close(new_socket)) < 0) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "close"; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, ERR_FAILED); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_FAILED; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TCPClientSocket> tcp_socket(new TCPClientSocket( 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddressList(address), 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.net_log(), net_log_.source())); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int adopt_result = tcp_socket->AdoptSocket(new_socket); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (adopt_result != OK) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HANDLE_EINTR(close(new_socket)) < 0) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "close"; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, adopt_result); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return adopt_result; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket->reset(tcp_socket.release()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_.EndEvent(NetLog::TYPE_TCP_ACCEPT, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateNetLogIPEndPointCallback(&address)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPServerSocketLibevent::Close() { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket_ != kInvalidSocket) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ok); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HANDLE_EINTR(close(socket_)) < 0) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "close"; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = kInvalidSocket; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPServerSocketLibevent::OnFileCanReadWithoutBlocking(int fd) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = AcceptInternal(accept_socket_); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != ERR_IO_PENDING) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_socket_ = NULL; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ok = accept_socket_watcher_.StopWatchingFileDescriptor(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ok); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback callback = accept_callback_; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_callback_.Reset(); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(result); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TCPServerSocketLibevent::OnFileCanWriteWithoutBlocking(int fd) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 224