mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-10 10:47:16 +00:00
Enhance UdpSocket error handling and usability
- Introduced a new `quarantine_socket` function to centralize error handling for socket operations, improving code clarity and maintainability. - Updated error handling in `UdpSocket` methods to utilize `quarantine_socket`, ensuring consistent logging and socket management across setup, send, and receive operations. - Added a `cancel` method to `UdpSocket` to safely cancel socket operations when the socket is not usable, enhancing robustness in error scenarios. - Introduced a `m_socket_usable` flag to track socket state, preventing operations on unusable sockets and improving overall stability.
This commit is contained in:
@@ -19,6 +19,26 @@ namespace endian = boost::endian;
|
|||||||
namespace asio = boost::asio;
|
namespace asio = boost::asio;
|
||||||
using boost::asio::ip::udp;
|
using boost::asio::ip::udp;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void quarantine_socket(udp::socket& socket, bool& socket_usable, const char* action, const std::exception& e)
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
socket_usable = false;
|
||||||
|
boost::system::error_code ec;
|
||||||
|
socket.cancel(ec);
|
||||||
|
socket.close(ec);
|
||||||
|
BOOST_LOG_TRIVIAL(error) << action << ": " << e.what();
|
||||||
|
#else
|
||||||
|
(void) socket;
|
||||||
|
(void) socket_usable;
|
||||||
|
(void) action;
|
||||||
|
BOOST_LOG_TRIVIAL(error) << e.what();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@@ -649,7 +669,7 @@ UdpSocket::UdpSocket( Bonjour::ReplyFn replyfn, const asio::ip::address& multica
|
|||||||
BOOST_LOG_TRIVIAL(info) << "Socket created. Multicast: " << multicast_address << ". Interface: " << interface_address;
|
BOOST_LOG_TRIVIAL(info) << "Socket created. Multicast: " << multicast_address << ". Interface: " << interface_address;
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << e.what();
|
quarantine_socket(socket, m_socket_usable, "UdpSocket setup failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,7 +693,7 @@ UdpSocket::UdpSocket( Bonjour::ReplyFn replyfn, const asio::ip::address& multica
|
|||||||
BOOST_LOG_TRIVIAL(info) << "Socket created. Multicast: " << multicast_address;
|
BOOST_LOG_TRIVIAL(info) << "Socket created. Multicast: " << multicast_address;
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << e.what();
|
quarantine_socket(socket, m_socket_usable, "UdpSocket setup failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -695,8 +715,20 @@ UdpSocket::~UdpSocket()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UdpSocket::cancel()
|
||||||
|
{
|
||||||
|
if (!m_socket_usable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
boost::system::error_code ec;
|
||||||
|
socket.cancel(ec);
|
||||||
|
}
|
||||||
|
|
||||||
void UdpSocket::send()
|
void UdpSocket::send()
|
||||||
{
|
{
|
||||||
|
if (!m_socket_usable)
|
||||||
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const auto& request : requests)
|
for (const auto& request : requests)
|
||||||
socket.send_to(asio::buffer(request.m_data), mcast_endpoint);
|
socket.send_to(asio::buffer(request.m_data), mcast_endpoint);
|
||||||
@@ -705,12 +737,15 @@ void UdpSocket::send()
|
|||||||
async_receive();
|
async_receive();
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << e.what();
|
quarantine_socket(socket, m_socket_usable, "UdpSocket send failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UdpSocket::async_receive()
|
void UdpSocket::async_receive()
|
||||||
{
|
{
|
||||||
|
if (!m_socket_usable)
|
||||||
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// our session to hold the buffer + endpoint
|
// our session to hold the buffer + endpoint
|
||||||
auto session = create_session();
|
auto session = create_session();
|
||||||
@@ -719,12 +754,15 @@ void UdpSocket::async_receive()
|
|||||||
, boost::bind(&UdpSocket::receive_handler, this, session, asio::placeholders::error, asio::placeholders::bytes_transferred));
|
, boost::bind(&UdpSocket::receive_handler, this, session, asio::placeholders::error, asio::placeholders::bytes_transferred));
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << e.what();
|
quarantine_socket(socket, m_socket_usable, "UdpSocket receive setup failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UdpSocket::receive_handler(SharedSession session, const boost::system::error_code& error, size_t bytes)
|
void UdpSocket::receive_handler(SharedSession session, const boost::system::error_code& error, size_t bytes)
|
||||||
{
|
{
|
||||||
|
if (!m_socket_usable)
|
||||||
|
return;
|
||||||
|
|
||||||
// let io_service to handle the datagram on session
|
// let io_service to handle the datagram on session
|
||||||
// from boost documentation io_service::post:
|
// from boost documentation io_service::post:
|
||||||
// The io_service guarantees that the handler will only be called in a thread in which the run(), run_one(), poll() or poll_one() member functions is currently being invoked.
|
// The io_service guarantees that the handler will only be called in a thread in which the run(), run_one(), poll() or poll_one() member functions is currently being invoked.
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ public:
|
|||||||
|
|
||||||
void send();
|
void send();
|
||||||
void async_receive();
|
void async_receive();
|
||||||
void cancel() { socket.cancel(); }
|
void cancel();
|
||||||
protected:
|
protected:
|
||||||
void receive_handler(SharedSession session, const boost::system::error_code& error, size_t bytes);
|
void receive_handler(SharedSession session, const boost::system::error_code& error, size_t bytes);
|
||||||
virtual SharedSession create_session() const = 0;
|
virtual SharedSession create_session() const = 0;
|
||||||
@@ -172,6 +172,7 @@ protected:
|
|||||||
boost::asio::ip::udp::endpoint mcast_endpoint;
|
boost::asio::ip::udp::endpoint mcast_endpoint;
|
||||||
std::shared_ptr< boost::asio::io_service > io_service;
|
std::shared_ptr< boost::asio::io_service > io_service;
|
||||||
std::vector<BonjourRequest> requests;
|
std::vector<BonjourRequest> requests;
|
||||||
|
bool m_socket_usable { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
class LookupSocket : public UdpSocket
|
class LookupSocket : public UdpSocket
|
||||||
|
|||||||
Reference in New Issue
Block a user