| Index: net/udp/udp_socket_libevent.cc
 | 
| diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc
 | 
| index 7c75ce39a59b457bf013d75acacc5ed661cdd184..de24253539f2ab4198fdfe29861ed2f351d71be7 100644
 | 
| --- a/net/udp/udp_socket_libevent.cc
 | 
| +++ b/net/udp/udp_socket_libevent.cc
 | 
| @@ -63,6 +63,8 @@ int MapPosixError(int os_error) {
 | 
|        return ERR_ADDRESS_INVALID;
 | 
|      case EMSGSIZE:
 | 
|        return ERR_MSG_TOO_BIG;
 | 
| +    case ENOTCONN:
 | 
| +      return ERR_SOCKET_NOT_CONNECTED;
 | 
|      case 0:
 | 
|        return OK;
 | 
|      default:
 | 
| @@ -99,9 +101,21 @@ UDPSocketLibevent::~UDPSocketLibevent() {
 | 
|  }
 | 
|  
 | 
|  void UDPSocketLibevent::Close() {
 | 
| +  DCHECK(CalledOnValidThread());
 | 
| +
 | 
| +  if (read_callback_)
 | 
| +    DoReadCallback(ERR_ABORTED);
 | 
| +  if (write_callback_)
 | 
| +    DoReadCallback(ERR_ABORTED);
 | 
| +
 | 
|    if (!is_connected())
 | 
|      return;
 | 
|  
 | 
| +  bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
 | 
| +  DCHECK(ok);
 | 
| +  ok = write_socket_watcher_.StopWatchingFileDescriptor();
 | 
| +  DCHECK(ok);
 | 
| +
 | 
|    if (HANDLE_EINTR(close(socket_)) < 0)
 | 
|      PLOG(ERROR) << "close";
 | 
|  
 | 
| @@ -161,10 +175,7 @@ int UDPSocketLibevent::Read(IOBuffer* buf,
 | 
|    DCHECK(callback);  // Synchronous operation not supported
 | 
|    DCHECK_GT(buf_len, 0);
 | 
|  
 | 
| -  read_buf_ = buf;
 | 
| -  read_buf_len_ = buf_len;
 | 
| -
 | 
| -  int nread = InternalRead();
 | 
| +  int nread = InternalRead(buf, buf_len);
 | 
|    if (nread != ERR_IO_PENDING)
 | 
|      return nread;
 | 
|  
 | 
| @@ -175,6 +186,8 @@ int UDPSocketLibevent::Read(IOBuffer* buf,
 | 
|      return MapPosixError(errno);
 | 
|    }
 | 
|  
 | 
| +  read_buf_ = buf;
 | 
| +  read_buf_len_ = buf_len;
 | 
|    read_callback_ = callback;
 | 
|    return ERR_IO_PENDING;
 | 
|  }
 | 
| @@ -232,7 +245,7 @@ int UDPSocketLibevent::Connect(const IPEndPoint& address) {
 | 
|    DCHECK(!remote_address_.get());
 | 
|    int rv = CreateSocket(address);
 | 
|    if (rv < 0)
 | 
| -    return MapPosixError(rv);
 | 
| +    return rv;
 | 
|  
 | 
|    struct sockaddr_storage addr_storage;
 | 
|    size_t addr_len = sizeof(addr_storage);
 | 
| @@ -242,7 +255,7 @@ int UDPSocketLibevent::Connect(const IPEndPoint& address) {
 | 
|  
 | 
|    rv = HANDLE_EINTR(connect(socket_, addr, addr_len));
 | 
|    if (rv < 0)
 | 
| -    return MapPosixError(rv);
 | 
| +    return MapPosixError(errno);
 | 
|  
 | 
|    remote_address_.reset(new IPEndPoint(address));
 | 
|    return rv;
 | 
| @@ -253,7 +266,7 @@ int UDPSocketLibevent::Bind(const IPEndPoint& address) {
 | 
|    DCHECK(!local_address_.get());
 | 
|    int rv = CreateSocket(address);
 | 
|    if (rv < 0)
 | 
| -    return MapPosixError(rv);
 | 
| +    return rv;
 | 
|  
 | 
|    struct sockaddr_storage addr_storage;
 | 
|    size_t addr_len = sizeof(addr_storage);
 | 
| @@ -263,7 +276,7 @@ int UDPSocketLibevent::Bind(const IPEndPoint& address) {
 | 
|  
 | 
|    rv = bind(socket_, addr, addr_len);
 | 
|    if (rv < 0)
 | 
| -    return MapPosixError(rv);
 | 
| +    return MapPosixError(errno);
 | 
|  
 | 
|    local_address_.reset(new IPEndPoint(address));
 | 
|    return rv;
 | 
| @@ -292,7 +305,7 @@ void UDPSocketLibevent::DoWriteCallback(int rv) {
 | 
|  }
 | 
|  
 | 
|  void UDPSocketLibevent::DidCompleteRead() {
 | 
| -  int result = InternalRead();
 | 
| +  int result = InternalRead(read_buf_, read_buf_len_);
 | 
|    if (result != ERR_IO_PENDING) {
 | 
|      read_buf_ = NULL;
 | 
|      read_buf_len_ = 0;
 | 
| @@ -305,9 +318,9 @@ void UDPSocketLibevent::DidCompleteRead() {
 | 
|  int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
 | 
|    socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0);
 | 
|    if (socket_ == kInvalidSocket)
 | 
| -    return errno;
 | 
| +    return MapPosixError(errno);
 | 
|    if (SetNonBlocking(socket_)) {
 | 
| -    const int err = errno;
 | 
| +    const int err = MapPosixError(errno);
 | 
|      Close();
 | 
|      return err;
 | 
|    }
 | 
| @@ -331,7 +344,7 @@ void UDPSocketLibevent::DidCompleteWrite() {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -int UDPSocketLibevent::InternalRead() {
 | 
| +int UDPSocketLibevent::InternalRead(IOBuffer* buf, int buf_len) {
 | 
|    int bytes_transferred;
 | 
|    int flags = 0;
 | 
|  
 | 
| @@ -341,8 +354,8 @@ int UDPSocketLibevent::InternalRead() {
 | 
|  
 | 
|    bytes_transferred =
 | 
|        HANDLE_EINTR(recvfrom(socket_,
 | 
| -                            read_buf_->data(),
 | 
| -                            read_buf_len_,
 | 
| +                            buf->data(),
 | 
| +                            buf_len,
 | 
|                              flags,
 | 
|                              addr,
 | 
|                              &addr_len));
 | 
| @@ -360,6 +373,7 @@ int UDPSocketLibevent::InternalRead() {
 | 
|    }
 | 
|    return result;
 | 
|  }
 | 
| +
 | 
|  int UDPSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) {
 | 
|    struct sockaddr_storage addr_storage;
 | 
|    size_t addr_len = sizeof(addr_storage);
 | 
| 
 |