* @brief A minimal RPC @b server using LibC functionality to setup the UDP socket, * and synchronous blocking POSIX calls to receive and send packets - * @b one at a time! */
| 6753 | * @b one at a time! |
| 6754 | */ |
| 6755 | class rpc_libc_server { |
| 6756 | int socket_descriptor_; |
| 6757 | sockaddr_in server_address_; |
| 6758 | std::atomic_bool should_stop_; |
| 6759 | |
| 6760 | public: |
| 6761 | rpc_libc_server(std::string const &server_address_str, std::uint16_t port, std::size_t max_concurrency) |
| 6762 | : should_stop_(false) { |
| 6763 | auto [socket_descriptor, server_address] = rpc_server_socket(port, server_address_str); |
| 6764 | socket_descriptor_ = socket_descriptor; |
| 6765 | server_address_ = server_address; |
| 6766 | |
| 6767 | // Let's make sure we don't block forever on `recvfrom` |
| 6768 | struct timeval duration; |
| 6769 | duration.tv_sec = 0; |
| 6770 | duration.tv_usec = to_microseconds(rpc_batch_timeout_k).count(); |
| 6771 | if (setsockopt(socket_descriptor_, SOL_SOCKET, SO_RCVTIMEO, &duration, sizeof(duration)) < 0) |
| 6772 | raise_system_error("Failed to set sockets batch timeout"); |
| 6773 | } |
| 6774 | |
| 6775 | ~rpc_libc_server() noexcept {} |
| 6776 | void close() noexcept { ::close(socket_descriptor_); } |
| 6777 | void stop() noexcept { should_stop_.store(true, std::memory_order_seq_cst); } |
| 6778 | |
| 6779 | void operator()() noexcept { |
| 6780 | sockaddr_in client_address; |
| 6781 | socklen_t client_len = sizeof(client_address); |
| 6782 | rpc_buffer_t receive_buffer, send_buffer; |
| 6783 | |
| 6784 | while (!should_stop_.load(std::memory_order_seq_cst)) { |
| 6785 | ssize_t received_length = recvfrom(socket_descriptor_, receive_buffer.data(), receive_buffer.size(), 0, |
| 6786 | reinterpret_cast<sockaddr *>(&client_address), &client_len); |
| 6787 | if (received_length <= 0) continue; |
| 6788 | std::size_t reply_length = |
| 6789 | packet_modify(receive_buffer.data(), static_cast<std::size_t>(received_length), send_buffer.data()); |
| 6790 | sendto(socket_descriptor_, send_buffer.data(), reply_length, 0, |
| 6791 | reinterpret_cast<sockaddr *>(&client_address), client_len); |
| 6792 | } |
| 6793 | } |
| 6794 | }; |
| 6795 | |
| 6796 | /** |
| 6797 | * @brief A minimal RPC @b client using LibC functionality to setup the UDP socket, |
nothing calls this directly
no outgoing calls
no test coverage detected