@@ -64,60 +64,76 @@ class server : public endpoint<connection<config>,config> {
64
64
// / Type of the endpoint component of this server
65
65
typedef endpoint<connection_type,config> endpoint_type;
66
66
67
-
68
- // TODO: clean up these types
69
-
70
67
explicit server () : endpoint_type(true )
71
68
{
72
69
endpoint_type::m_alog.write (log ::alevel::devel, " server constructor" );
73
70
}
74
71
75
- // return an initialized connection_ptr. Call start() on this object to
76
- // begin the processing loop.
72
+ // / Create and initialize a new connection
73
+ /* *
74
+ * The connection will be initialized and ready to begin. Call its start()
75
+ * method to begin the processing loop.
76
+ *
77
+ * Note: The connection must either be started or terminated using
78
+ * connection::terminate in order to avoid memory leaks.
79
+ *
80
+ * @return A pointer to the new connection.
81
+ */
77
82
connection_ptr get_connection () {
78
- connection_ptr con = endpoint_type::create_connection ();
79
-
80
- return con;
83
+ return endpoint_type::create_connection ();
81
84
}
82
85
83
- // Starts the server's async connection acceptance loop.
84
- void start_accept () {
86
+ // / Starts the server's async connection acceptance loop (exception free)
87
+ /* *
88
+ * Initiates the server connection acceptance loop. Must be called after
89
+ * listen. This method will have no effect until the underlying io_service
90
+ * starts running. It may be called after the io_service is already running.
91
+ *
92
+ * Refer to documentation for the transport policy you are using for
93
+ * instructions on how to stop this acceptance loop.
94
+ *
95
+ * @param [out] ec A status code indicating an error, if any.
96
+ */
97
+ void start_accept (lib::error_code & ec) {
85
98
if (!transport_type::is_listening ()) {
86
- endpoint_type::m_elog.write (log ::elevel::info,
87
- " Stopping acceptance of new connections because the underlying transport is no longer listening." );
99
+ ec = error::make_error_code (error::async_accept_not_listening);
88
100
return ;
89
101
}
90
102
103
+ ec = lib::error_code ();
91
104
connection_ptr con = get_connection ();
92
105
93
- lib::error_code ec;
94
-
95
106
transport_type::async_accept (
96
107
lib::static_pointer_cast<transport_con_type>(con),
97
- lib::bind (
98
- &type::handle_accept,
99
- this ,
100
- con,
101
- lib::placeholders::_1
102
- ),
108
+ lib::bind (&type::handle_accept,this ,con,lib::placeholders::_1),
103
109
ec
104
110
);
105
111
106
- if (ec == error::async_accept_not_listening) {
107
- endpoint_type::m_elog.write (log ::elevel::info,
108
- " Stopping acceptance of new connections because the underlying transport is no longer listening." );
109
- } else if (ec) {
110
- endpoint_type::m_elog.write (log ::elevel::rerror,
111
- " start_accept error: " +ec.message ());
112
+ if (ec && con) {
113
+ // If the connection was constructed but the accept failed,
114
+ // terminate the connection to prevent memory leaks
115
+ con->terminate (lib::error_code ());
112
116
}
113
-
114
- if (ec && con) {
115
- // Terminate the connection to prevent memory leaks.
116
- lib::error_code con_ec;
117
- con->terminate (con_ec);
118
- }
119
- }
117
+ }
120
118
119
+ // / Starts the server's async connection acceptance loop
120
+ /* *
121
+ * Initiates the server connection acceptance loop. Must be called after
122
+ * listen. This method will have no effect until the underlying io_service
123
+ * starts running. It may be called after the io_service is already running.
124
+ *
125
+ * Refer to documentation for the transport policy you are using for
126
+ * instructions on how to stop this acceptance loop.
127
+ */
128
+ void start_accept () {
129
+ lib::error_code ec;
130
+ start_accept (ec);
131
+ if (ec) {
132
+ throw ec;
133
+ }
134
+ }
135
+
136
+ // / Handler callback for start_accept
121
137
void handle_accept (connection_ptr con, lib::error_code const & ec) {
122
138
if (ec) {
123
139
con->terminate (ec);
@@ -133,10 +149,16 @@ class server : public endpoint<connection<config>,config> {
133
149
con->start ();
134
150
}
135
151
136
-
137
- start_accept ();
152
+ lib::error_code start_ec;
153
+ start_accept (start_ec);
154
+ if (start_ec == error::async_accept_not_listening) {
155
+ endpoint_type::m_elog.write (log ::elevel::info,
156
+ " Stopping acceptance of new connections because the underlying transport is no longer listening." );
157
+ } else if (start_ec) {
158
+ endpoint_type::m_elog.write (log ::elevel::rerror,
159
+ " Restarting async_accept loop failed: " +ec.message ());
160
+ }
138
161
}
139
- private:
140
162
};
141
163
142
164
} // namespace websocketpp
0 commit comments