summaryrefslogtreecommitdiff
path: root/ace/Asynch_Acceptor.h
blob: cd8b286b6c3cbc9e84ce5127b4fffde53189b3e2 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* -*- C++ -*- */

//=============================================================================
/**
 *  @file    Asynch_Acceptor.h
 *
 *  $Id$
 *
 *  @author Irfan Pyarali (irfan@cs.wustl.edu)
 */
//=============================================================================

#ifndef ACE_ASYNCH_ACCEPTOR_H
#define ACE_ASYNCH_ACCEPTOR_H
#include "ace/pre.h"

#include "ace/OS.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#if defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)
// This only works on platforms that support async i/o.

#include "ace/Asynch_IO.h"

// Forward declarations
class ACE_Message_Block;
class ACE_INET_Addr;

/**
 * @class ACE_Asynch_Acceptor
 *
 * @brief This class is an example of the Acceptor Pattern.  This class
 * will accept new connections and create new HANDLER to handle
 * the new connections.
 *
 * Unlike the <ACE_Acceptor>, however, this class is designed to
 * be used asynchronously.
 */
template <class HANDLER>
class ACE_Asynch_Acceptor : public ACE_Handler
{
public:
  /// A do nothing constructor.
  ACE_Asynch_Acceptor (void);

  /// Virtual destruction
  virtual ~ACE_Asynch_Acceptor (void);

  /**
   * This starts the listening process at the port specified by
   * <address>.  ACE_Asynch_Acceptor initiates the AcceptEx calls with
   * <bytes_to_read>.  The buffer for the initial data will be created
   * by ACE_Asynch_Acceptor.  This buffer will be passed to the
   * handler in the <ACE_Service_Handler::open> callback.  If this
   * buffer is required past the <open> callback, the
   * ACE_Service_Handler must copy the data.  If the <pass_addresses>
   * flag is set, ACE_Asynch_Acceptor will call
   * <ACE_Service_Handler::addresses> before calling
   * <ACE_Service_Handler::open>.  The <backlog> parameter specifies
   * the listen backlog and the outstanding AcceptEx calls.
   * <number_of_initial_accepts> is the number of asynchronous accepts
   * that are started at the end of <open>.  If
   * <number_of_initial_accepts> is -1, then
   * <number_of_initial_accepts> is set to <backlog> and hence
   * <backlog> number of asynchronous accepts are started.
   */
  virtual int open (const ACE_INET_Addr &address,
                    size_t bytes_to_read = 0,
                    int pass_addresses = 0,
                    int backlog = ACE_DEFAULT_BACKLOG,
                    int reuse_addr = 1,
                    ACE_Proactor *proactor = 0,
                    int validate_new_connection = 0,
                    int reissue_accept = 1,
                    int number_of_initial_accepts = -1);

  /// Get the underlying handle.
  virtual ACE_HANDLE get_handle (void) const;

  /**
   * Set the underlying listen handle. It is the user's responsibility
   * to make sure that the old listen handle has been appropriately
   * closed and the all outstanding asynchronous operations have
   * either completed or have been canceled on the old listen handle.
   */
  virtual void set_handle (ACE_HANDLE handle);

  /// This initiates a new asynchronous accept through the <AcceptEx>
  /// call.
  virtual int accept (size_t bytes_to_read = 0, const void *act = 0);

  /**
   * This cancels all pending accepts operations that were issued by
   * the calling thread.
   * Windows NT- The function does not cancel accept operations
   *             issued by other threads
   * POSIX     - all OK, it delegates cancelation to the
   *             ACE_POSIX_Asynch_Accept
   *
   */
  virtual int cancel (void);

  /**
   * Template method for address validation.
   *
   * Default implemenation always validates the remote address.
   */
  virtual int validate_new_connection (const ACE_INET_Addr &remote_address);

  /**
   * Template method for deciding whether to reissue accept.
   *
   * Default implemenation always returns this->reissue_accept_.
   */
  virtual int should_reissue_accept (void);

  //
  // These are low level tweaking methods
  //

  /// Set and get flag that indicates if parsing and passing of
  /// addresses to the service_handler is necessary.
  virtual int pass_addresses (void) const;
  virtual void pass_addresses (int new_value);

  /// Set and get flag that indicates if address validation is
  /// required.
  virtual int validate_new_connection (void) const;
  virtual void validate_new_connection (int new_value);

  /// Set and get flag that indicates if a new accept should be
  /// reissued when a accept completes.
  virtual int reissue_accept (void) const;
  virtual void reissue_accept (int new_value);

  /// Set and get bytes to be read with the <accept> call.
  virtual int bytes_to_read (void) const;
  virtual void bytes_to_read (int new_value);

  /// This is required by the AcceptEx call.
  static size_t address_size (void);

protected:

  /// This is called when an outstanding accept completes.
  virtual void handle_accept (const ACE_Asynch_Accept::Result &result);

  /// Return the listen handle.
  ACE_HANDLE handle (void) const;

  /// This parses the address from read buffer.
  void parse_address (const ACE_Asynch_Accept::Result &result,
                      ACE_INET_Addr &remote_address,
                      ACE_INET_Addr &local_address);

  /**
   * This is the template method used to create new handler.
   * Subclasses must overwrite this method if a new handler creation
   * strategy is required.
   */
  virtual HANDLER *make_handler (void);

private:
  /// Handle used to listen for new connections.
  ACE_HANDLE listen_handle_;

  /// <Asynch_Accept> used to make life easier :-)
  ACE_Asynch_Accept asynch_accept_;

  /// Flag that indicates if parsing of addresses is necessary.
  int pass_addresses_;

  /// Flag that indicates if address validation is required.
  int validate_new_connection_;

  /// Flag that indicates if a new accept should be reissued when a
  /// accept completes.
  int reissue_accept_;

  /// Bytes to be read with the <accept> call.
  int bytes_to_read_;
};

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Asynch_Acceptor.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */

#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Asynch_Acceptor.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */

#endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
#include "ace/post.h"
#endif /* ACE_ASYNCH_ACCEPTOR_H */