32 : thread_base(
"accept_worker")
34 , on_connection_(std::move(on_connection))
35 , on_maintenance_(std::move(on_maintenance)) {
66 return accepting_.load(std::memory_order_acquire);
70 std::ostringstream oss;
71 oss <<
"accept_worker{"
75 <<
", running=" << (is_running() ?
"true" :
"false")
91 int wsa_result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
92 if (wsa_result != 0) {
93 return kcenon::common::error_info(
"WSAStartup failed: " + std::to_string(wsa_result));
95 wsa_initialized_ =
true;
100 int err = WSAGetLastError();
102 wsa_initialized_ =
false;
103 return kcenon::common::error_info(
"Failed to create socket: " + std::to_string(err));
109 reinterpret_cast<const char*
>(&opt),
sizeof(opt));
117 addr.sin_family = AF_INET;
118 addr.sin_addr.s_addr = INADDR_ANY;
119 addr.sin_port = htons(
port_);
121 if (bind(
listen_socket_,
reinterpret_cast<sockaddr*
>(&addr),
sizeof(addr)) == SOCKET_ERROR) {
122 int err = WSAGetLastError();
126 wsa_initialized_ =
false;
127 return kcenon::common::error_info(
"Failed to bind to port " +
128 std::to_string(
port_) +
": " + std::to_string(err));
133 int err = WSAGetLastError();
137 wsa_initialized_ =
false;
138 return kcenon::common::error_info(
"Failed to listen: " + std::to_string(err));
144 return kcenon::common::error_info(
"Failed to create socket: " +
145 std::string(std::strerror(errno)));
150 setsockopt(
listen_socket_, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
160 addr.sin_family = AF_INET;
161 addr.sin_addr.s_addr = INADDR_ANY;
162 addr.sin_port = htons(
port_);
164 if (bind(
listen_socket_,
reinterpret_cast<sockaddr*
>(&addr),
sizeof(addr)) < 0) {
165 std::string err_msg = std::strerror(errno);
168 return kcenon::common::error_info(
"Failed to bind to port " +
169 std::to_string(
port_) +
": " + err_msg);
174 std::string err_msg = std::strerror(errno);
177 return kcenon::common::error_info(
"Failed to listen: " + err_msg);
181 accepting_.store(
true, std::memory_order_release);
182 return kcenon::common::ok();
190 return kcenon::common::ok();
202 int result = select(0, &readfds,
nullptr,
nullptr, &tv);
205 sockaddr_in client_addr{};
206 int addr_len =
sizeof(client_addr);
209 reinterpret_cast<sockaddr*
>(&client_addr),
212 if (client_socket != INVALID_SOCKET) {
224 closesocket(client_socket);
229 return kcenon::common::ok();
241 int result = select(
listen_socket_ + 1, &readfds,
nullptr,
nullptr, &tv);
244 sockaddr_in client_addr{};
245 socklen_t addr_len =
sizeof(client_addr);
248 reinterpret_cast<sockaddr*
>(&client_addr),
251 if (client_socket >= 0) {
263 close(client_socket);
273 return kcenon::common::ok();
279 accepting_.store(
false, std::memory_order_release);
286 if (wsa_initialized_) {
288 wsa_initialized_ =
false;
297 return kcenon::common::ok();
Worker thread for accepting incoming DICOM connections.
connection_callback on_connection_
Callback for new connections.
int backlog_
Maximum pending connections in listen queue.
result_void after_stop() override
Cleans up resources after the worker thread stops.
result_void do_work() override
Main work routine - checks for incoming connections.
void set_max_pending_connections(int backlog)
Sets the maximum number of pending connections in the listen queue.
common::VoidResult result_void
int listen_socket_
Listen socket file descriptor (POSIX)
std::string to_string() const override
Gets a string representation of the worker state.
uint64_t next_session_id()
Generates a unique session ID for new connections.
std::function< void()> maintenance_callback
Callback type for periodic maintenance tasks.
void on_stop_requested() override
Called when stop() is requested.
bool should_continue_work() const override
Determines whether there is pending work that must complete.
std::function< void(uint64_t session_id)> connection_callback
Callback type for new connection events.
result_void before_start() override
Initializes resources before the worker thread starts.
uint16_t port_
TCP port to listen on.
std::atomic< uint64_t > session_id_counter_
Session ID counter for unique connection identification.
maintenance_callback on_maintenance_
Optional callback for maintenance tasks.
uint16_t port() const noexcept
Gets the configured port number.
int max_pending_connections() const noexcept
Gets the current backlog setting.
accept_worker(uint16_t port, connection_callback on_connection, maintenance_callback on_maintenance=nullptr)
Constructs an accept_worker with the specified configuration.
bool is_accepting() const noexcept
Checks if the worker is actively accepting connections.
~accept_worker() override
Destructor.
std::atomic< bool > accepting_
Flag indicating if actively accepting connections.