Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2006-2009 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 #ifndef NET_SOCKET_TCP_CLIENT_SOCKET_LIBEVENT_H_
      6 #define NET_SOCKET_TCP_CLIENT_SOCKET_LIBEVENT_H_
      7 
      8 #include "base/message_loop.h"
      9 #include "base/ref_counted.h"
     10 #include "base/scoped_ptr.h"
     11 #include "net/base/address_list.h"
     12 #include "net/base/completion_callback.h"
     13 #include "net/socket/client_socket.h"
     14 
     15 struct event;  // From libevent
     16 
     17 namespace net {
     18 
     19 class LoadLog;
     20 
     21 // A client socket that uses TCP as the transport layer.
     22 class TCPClientSocketLibevent : public ClientSocket {
     23  public:
     24   // The IP address(es) and port number to connect to.  The TCP socket will try
     25   // each IP address in the list until it succeeds in establishing a
     26   // connection.
     27   explicit TCPClientSocketLibevent(const AddressList& addresses);
     28 
     29   virtual ~TCPClientSocketLibevent();
     30 
     31   // ClientSocket methods:
     32   virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
     33   virtual void Disconnect();
     34   virtual bool IsConnected() const;
     35   virtual bool IsConnectedAndIdle() const;
     36   virtual int GetPeerName(struct sockaddr* name, socklen_t* namelen);
     37 
     38   // Socket methods:
     39   // Multiple outstanding requests are not supported.
     40   // Full duplex mode (reading and writing at the same time) is supported
     41   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     42   virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     43   virtual bool SetReceiveBufferSize(int32 size);
     44   virtual bool SetSendBufferSize(int32 size);
     45 
     46  private:
     47   class ReadWatcher : public MessageLoopForIO::Watcher {
     48    public:
     49     explicit ReadWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {}
     50 
     51     // MessageLoopForIO::Watcher methods
     52 
     53     virtual void OnFileCanReadWithoutBlocking(int /* fd */) {
     54       if (socket_->read_callback_)
     55         socket_->DidCompleteRead();
     56     }
     57 
     58     virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {}
     59 
     60    private:
     61     TCPClientSocketLibevent* const socket_;
     62 
     63     DISALLOW_COPY_AND_ASSIGN(ReadWatcher);
     64   };
     65 
     66   class WriteWatcher : public MessageLoopForIO::Watcher {
     67    public:
     68     explicit WriteWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {}
     69 
     70     // MessageLoopForIO::Watcher methods
     71 
     72     virtual void OnFileCanReadWithoutBlocking(int /* fd */) {}
     73 
     74     virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {
     75       if (socket_->waiting_connect_) {
     76         socket_->DidCompleteConnect();
     77       } else if (socket_->write_callback_) {
     78         socket_->DidCompleteWrite();
     79       }
     80     }
     81 
     82    private:
     83     TCPClientSocketLibevent* const socket_;
     84 
     85     DISALLOW_COPY_AND_ASSIGN(WriteWatcher);
     86   };
     87 
     88   // Performs the actual connect().  Returns a net error code.
     89   int DoConnect();
     90 
     91   void DoReadCallback(int rv);
     92   void DoWriteCallback(int rv);
     93   void DidCompleteRead();
     94   void DidCompleteWrite();
     95   void DidCompleteConnect();
     96 
     97   int CreateSocket(const struct addrinfo* ai);
     98 
     99   int socket_;
    100 
    101   // The list of addresses we should try in order to establish a connection.
    102   AddressList addresses_;
    103 
    104   // Where we are in above list, or NULL if all addrinfos have been tried.
    105   const struct addrinfo* current_ai_;
    106 
    107   // Whether we're currently waiting for connect() to complete
    108   bool waiting_connect_;
    109 
    110   // The socket's libevent wrappers
    111   MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_;
    112   MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_;
    113 
    114   // The corresponding watchers for reads and writes.
    115   ReadWatcher read_watcher_;
    116   WriteWatcher write_watcher_;
    117 
    118   // The buffer used by OnSocketReady to retry Read requests
    119   scoped_refptr<IOBuffer> read_buf_;
    120   int read_buf_len_;
    121 
    122   // The buffer used by OnSocketReady to retry Write requests
    123   scoped_refptr<IOBuffer> write_buf_;
    124   int write_buf_len_;
    125 
    126   // External callback; called when read is complete.
    127   CompletionCallback* read_callback_;
    128 
    129   // External callback; called when write is complete.
    130   CompletionCallback* write_callback_;
    131 
    132   scoped_refptr<LoadLog> load_log_;
    133 
    134   DISALLOW_COPY_AND_ASSIGN(TCPClientSocketLibevent);
    135 };
    136 
    137 }  // namespace net
    138 
    139 #endif  // NET_SOCKET_TCP_CLIENT_SOCKET_LIBEVENT_H_
    140