@@ -49,7 +49,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
49
49
uint16_t concurrency = 1 ,
50
50
uint8_t timeout = 5 ,
51
51
typename Adaptor::context* adaptor_ctx = nullptr ):
52
- acceptor_ (io_context_,endpoint ),
52
+ acceptor_ (io_context_),
53
53
signals_ (io_context_),
54
54
tick_timer_ (io_context_),
55
55
handler_ (handler),
@@ -59,7 +59,45 @@ namespace crow // NOTE: Already documented in "crow/app.h"
59
59
task_queue_length_pool_ (concurrency_ - 1 ),
60
60
middlewares_ (middlewares),
61
61
adaptor_ctx_ (adaptor_ctx)
62
- {}
62
+ {
63
+ if (startup_failed_) {
64
+ CROW_LOG_ERROR << " Startup failed; not running server." ;
65
+ return ;
66
+ }
67
+
68
+ error_code ec;
69
+
70
+ acceptor_.open (endpoint.protocol (), ec);
71
+ if (ec) {
72
+ CROW_LOG_ERROR << " Failed to open acceptor: " << ec.message ();
73
+ startup_failed_ = true ;
74
+ return ;
75
+ }
76
+
77
+ acceptor_.set_option (tcp::acceptor::reuse_address (true ), ec);
78
+ if (ec) {
79
+ CROW_LOG_ERROR << " Failed to set socket option: " << ec.message ();
80
+ startup_failed_ = true ;
81
+ return ;
82
+ }
83
+
84
+ acceptor_.bind (endpoint, ec);
85
+ if (ec) {
86
+ CROW_LOG_ERROR << " Failed to bind to " << endpoint.address ().to_string ()
87
+ << " :" << endpoint.port () << " - " << ec.message ();
88
+ startup_failed_ = true ;
89
+ return ;
90
+ }
91
+
92
+ acceptor_.listen (tcp::acceptor::max_listen_connections, ec);
93
+ if (ec) {
94
+ CROW_LOG_ERROR << " Failed to listen on port: " << ec.message ();
95
+ startup_failed_ = true ;
96
+ return ;
97
+ }
98
+
99
+
100
+ }
63
101
64
102
void set_tick_function (std::chrono::milliseconds d, std::function<void ()> f)
65
103
{
@@ -80,6 +118,12 @@ namespace crow // NOTE: Already documented in "crow/app.h"
80
118
81
119
void run ()
82
120
{
121
+
122
+ if (startup_failed_) {
123
+ CROW_LOG_ERROR << " Server startup failed. Aborting run()." ;
124
+ return ;
125
+ }
126
+
83
127
uint16_t worker_thread_count = concurrency_ - 1 ;
84
128
for (int i = 0 ; i < worker_thread_count; i++)
85
129
io_context_pool_.emplace_back (new asio::io_context ());
@@ -215,13 +259,14 @@ namespace crow // NOTE: Already documented in "crow/app.h"
215
259
std::cv_status wait_for_start (std::chrono::steady_clock::time_point wait_until)
216
260
{
217
261
std::unique_lock<std::mutex> lock (start_mutex_);
218
-
262
+
219
263
std::cv_status status = std::cv_status::no_timeout;
220
- while (!server_started_ && ( status== std::cv_status::no_timeout ) )
221
- status = cv_started_.wait_until (lock,wait_until);
264
+ while (!server_started_ && !startup_failed_ && status == std::cv_status::no_timeout)
265
+ status = cv_started_.wait_until (lock, wait_until);
222
266
return status;
223
267
}
224
268
269
+
225
270
void signal_clear ()
226
271
{
227
272
signals_.clear ();
@@ -298,6 +343,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
298
343
tcp::acceptor acceptor_;
299
344
bool shutting_down_ = false ;
300
345
bool server_started_{false };
346
+ bool startup_failed_ = false ;
301
347
std::condition_variable cv_started_;
302
348
std::mutex start_mutex_;
303
349
asio::signal_set signals_;
0 commit comments