diff --git a/Common/Cpp/Sockets/ClientSocket_Qt.cpp b/Common/Cpp/Sockets/ClientSocket_Qt.cpp index 7fbdc75abf..62f933d034 100644 --- a/Common/Cpp/Sockets/ClientSocket_Qt.cpp +++ b/Common/Cpp/Sockets/ClientSocket_Qt.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include "Common/Qt/QtThreadPool.h" @@ -93,25 +94,27 @@ size_t ClientSocket_Qt::send(const void* data, size_t bytes){ return 0; } - SendData send_data; - send_data.packet.assign((const char*)data, bytes); + QSharedPointer send_data = QSharedPointer::create(); + send_data->packet.assign((const char*)data, bytes); - emit internal_send(&send_data); + emit internal_send(send_data); // Wait for the socket's event thread to finish writing the packet. // The timeout covers the case where "close()" destroys the socket // before the queued call ever runs, in which case it will never - // complete on its own. + // complete on its own. The shared ownership makes the timeout + // safe: if it expires, the queued call's own copy keeps the + // payload alive until it runs. { - std::unique_lock lg(send_data.lock); - send_data.cv.wait_for( + std::unique_lock lg(send_data->lock); + send_data->cv.wait_for( lg, std::chrono::seconds(5), - [&send_data]{ return send_data.done; } + [&send_data]{ return send_data->done; } ); } - return send_data.bytes_sent; + return send_data->bytes_sent; } void ClientSocket_Qt::connection_failed(const std::string& error_message){ @@ -238,7 +241,7 @@ std::unique_ptr ClientSocket_Qt::make_socket(){ ); QObject::connect( this, &ClientSocket_Qt::internal_send, - socket.get(), [this, sock = socket.get()](SendData* send_data){ + socket.get(), [this, sock = socket.get()](QSharedPointer send_data){ { std::lock_guard lg(m_lock); m_sends_in_flight.fetch_add(1, std::memory_order_acq_rel); diff --git a/Common/Cpp/Sockets/ClientSocket_Qt.h b/Common/Cpp/Sockets/ClientSocket_Qt.h index c944ec2b6f..f03f9b59b4 100644 --- a/Common/Cpp/Sockets/ClientSocket_Qt.h +++ b/Common/Cpp/Sockets/ClientSocket_Qt.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "Common/Cpp/Concurrency/Mutex.h" #include "Common/Cpp/Concurrency/ConditionVariable.h" #include "AbstractClientSocket.h" @@ -60,7 +61,7 @@ class ClientSocket_Qt final : public QObject, public AbstractClientSocket{ signals: void internal_connect(const std::string& address, uint16_t port); - void internal_send(SendData* send_data); + void internal_send(QSharedPointer send_data); private: