@@ -49,7 +49,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
4949 uint16_t concurrency = 1 ,
5050 uint8_t timeout = 5 ,
5151 typename Adaptor::context* adaptor_ctx = nullptr ):
52- acceptor_ (io_context_,endpoint ),
52+ acceptor_ (io_context_),
5353 signals_ (io_context_),
5454 tick_timer_ (io_context_),
5555 handler_ (handler),
@@ -59,7 +59,45 @@ namespace crow // NOTE: Already documented in "crow/app.h"
5959 task_queue_length_pool_ (concurrency_ - 1 ),
6060 middlewares_ (middlewares),
6161 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+ }
63101
64102 void set_tick_function (std::chrono::milliseconds d, std::function<void ()> f)
65103 {
@@ -80,6 +118,12 @@ namespace crow // NOTE: Already documented in "crow/app.h"
80118
81119 void run ()
82120 {
121+
122+ if (startup_failed_) {
123+ CROW_LOG_ERROR << " Server startup failed. Aborting run()." ;
124+ return ;
125+ }
126+
83127 uint16_t worker_thread_count = concurrency_ - 1 ;
84128 for (int i = 0 ; i < worker_thread_count; i++)
85129 io_context_pool_.emplace_back (new asio::io_context ());
@@ -215,13 +259,14 @@ namespace crow // NOTE: Already documented in "crow/app.h"
215259 std::cv_status wait_for_start (std::chrono::steady_clock::time_point wait_until)
216260 {
217261 std::unique_lock<std::mutex> lock (start_mutex_);
218-
262+
219263 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);
222266 return status;
223267 }
224268
269+
225270 void signal_clear ()
226271 {
227272 signals_.clear ();
@@ -298,6 +343,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
298343 tcp::acceptor acceptor_;
299344 bool shutting_down_ = false ;
300345 bool server_started_{false };
346+ bool startup_failed_ = false ;
301347 std::condition_variable cv_started_;
302348 std::mutex start_mutex_;
303349 asio::signal_set signals_;
0 commit comments