summaryrefslogtreecommitdiffstats
path: root/net/base/listen_socket.h
blob: 923d36145ebc96435d758f8153b32e4efff18acc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TCP/IP server that handles IO asynchronously in the specified MessageLoop.
// These objects are NOT thread safe.  They use WSAEVENT handles to monitor
// activity in a given MessageLoop.  This means that callbacks will
// happen in that loop's thread always and that all other methods (including
// constructors and destructors) should also be called from the same thread.

#ifndef NET_BASE_LISTEN_SOCKET_H_
#define NET_BASE_LISTEN_SOCKET_H_

#include "build/build_config.h"

#if defined(OS_WIN)
#include <winsock2.h>
#endif
#include <string>
#if defined(OS_WIN)
#include "base/object_watcher.h"
#elif defined(OS_POSIX)
#include "base/message_loop.h"
#endif

#include "base/basictypes.h"
#include "base/ref_counted.h"

#if defined(OS_POSIX)
struct event;  // From libevent
typedef int SOCKET;
#endif

// Implements a raw socket interface
class ListenSocket : public base::RefCountedThreadSafe<ListenSocket>,
#if defined(OS_WIN)
                     public base::ObjectWatcher::Delegate
#elif defined(OS_POSIX)
                     public MessageLoopForIO::Watcher
#endif
{
 public:
  // TODO(erikkay): this delegate should really be split into two parts
  // to split up the listener from the connected socket.  Perhaps this class
  // should be split up similarly.
  class ListenSocketDelegate {
   public:
    virtual ~ListenSocketDelegate() {}

    // server is the original listening Socket, connection is the new
    // Socket that was created.  Ownership of connection is transferred
    // to the delegate with this call.
    virtual void DidAccept(ListenSocket *server, ListenSocket *connection) = 0;
    virtual void DidRead(ListenSocket *connection,
                         const char* data,
                         int len) = 0;
    virtual void DidClose(ListenSocket *sock) = 0;
  };

  // Listen on port for the specified IP address.  Use 127.0.0.1 to only
  // accept local connections.
  static ListenSocket* Listen(std::string ip, int port,
                              ListenSocketDelegate* del);

  // Send data to the socket.
  void Send(const char* bytes, int len, bool append_linefeed = false);
  void Send(const std::string& str, bool append_linefeed = false);

  // NOTE: This is for unit test use only!
  // Pause/Resume calling Read().  Note that ResumeReads() will also call
  // Read() if there is anything to read.
  void PauseReads();
  void ResumeReads();

 protected:
  friend class base::RefCountedThreadSafe<ListenSocket>;

  static const SOCKET kInvalidSocket;
  static const int kSocketError;

  ListenSocket(SOCKET s, ListenSocketDelegate* del);
  virtual ~ListenSocket();
  static SOCKET Listen(std::string ip, int port);
  // if valid, returned SOCKET is non-blocking
  static SOCKET Accept(SOCKET s);

  virtual void SendInternal(const char* bytes, int len);

  virtual void Listen();
  virtual void Accept();
  virtual void Read();
  virtual void Close();
  virtual void CloseSocket(SOCKET s);

  enum WaitState {
    NOT_WAITING      = 0,
    WAITING_ACCEPT   = 1,
    WAITING_READ     = 3,
    WAITING_CLOSE    = 4
  };
  // Pass any value in case of Windows, because in Windows
  // we are not using state.
  void WatchSocket(WaitState state);
  void UnwatchSocket();

#if defined(OS_WIN)
  // ObjectWatcher delegate
  virtual void OnObjectSignaled(HANDLE object);
  base::ObjectWatcher watcher_;
  HANDLE socket_event_;
#elif defined(OS_POSIX)
  WaitState wait_state_;
  // The socket's libevent wrapper
  MessageLoopForIO::FileDescriptorWatcher watcher_;
  // Called by MessagePumpLibevent when the socket is ready to do I/O
  void OnFileCanReadWithoutBlocking(int fd);
  void OnFileCanWriteWithoutBlocking(int fd);
#endif

  SOCKET socket_;
  ListenSocketDelegate *socket_delegate_;

 private:
  bool reads_paused_;
  bool has_pending_reads_;

  DISALLOW_COPY_AND_ASSIGN(ListenSocket);
};

#endif  // NET_BASE_LISTEN_SOCKET_H_