Skip to content

Commit b3140c3

Browse files
committed
Fix Qt socket deadlock across parallel send/receive.
1 parent db41c7a commit b3140c3

File tree

5 files changed

+36
-8
lines changed

5 files changed

+36
-8
lines changed

Common/Cpp/Sockets/AbstractClientSocket.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class AbstractClientSocket{
5959
virtual void close() noexcept = 0;
6060
virtual void connect(const std::string& address, uint16_t port) = 0;
6161

62-
virtual size_t blocking_send(const void* data, size_t bytes) = 0;
62+
virtual size_t send(const void* data, size_t bytes) = 0;
6363

6464

6565
protected:

Common/Cpp/Sockets/ClientSocket_POSIX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class ClientSocket_POSIX final : public AbstractClientSocket{
6767
}
6868

6969

70-
virtual size_t blocking_send(const void* data, size_t bytes) override{
70+
virtual size_t send(const void* data, size_t bytes) override{
7171
if (m_socket == -1){
7272
return 0;
7373
}

Common/Cpp/Sockets/ClientSocket_Qt.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ class ClientSocket_Qt final : public QThread, public AbstractClientSocket{
6262
emit internal_connect(address, port);
6363
}
6464

65-
virtual size_t blocking_send(const void* data, size_t bytes) override{
66-
// cout << "blocking_send() - start: " << std::string((const char*)data, bytes) << endl;
65+
virtual size_t send(const void* data, size_t bytes) override{
66+
// cout << "send() - start: " << std::string((const char*)data, bytes) << endl;
67+
emit internal_send(std::string((const char*)data, bytes));
68+
return bytes;
6769

70+
#if 0
6871
SendData send_data;
6972
send_data.data = data;
7073
send_data.total_bytes = bytes;
@@ -77,14 +80,15 @@ class ClientSocket_Qt final : public QThread, public AbstractClientSocket{
7780
return send_data.data == nullptr || m_socket == nullptr;
7881
});
7982

80-
// cout << "blocking_send() - end: " << std::string((const char*)data, bytes) << endl;
83+
// cout << "send() - end: " << std::string((const char*)data, bytes) << endl;
8184
return send_data.bytes_sent;
85+
#endif
8286
}
8387

8488

8589
signals:
8690
void internal_connect(const std::string& address, uint16_t port);
87-
void send(void* data);
91+
void internal_send(std::string packet);
8892

8993
private:
9094
virtual void run() override{
@@ -134,6 +138,29 @@ class ClientSocket_Qt final : public QThread, public AbstractClientSocket{
134138
m_socket->connectToHost(QHostAddress(QString::fromStdString(address)), port);
135139
}
136140
);
141+
QThread::connect(
142+
this, &ClientSocket_Qt::internal_send,
143+
&socket, [this](std::string packet){
144+
// cout << "internal_send() - enter: " << packet.data() << endl;
145+
146+
size_t bytes = packet.size();
147+
148+
const char* ptr = (const char*)packet.data();
149+
while (bytes > 0 && m_socket->state() == QAbstractSocket::ConnectedState){
150+
qint64 current_sent = m_socket->write(ptr, bytes);
151+
if (current_sent <= 0){
152+
break;
153+
}
154+
ptr += current_sent;
155+
bytes -= current_sent;
156+
}
157+
158+
m_socket->flush();
159+
160+
// cout << "internal_send() - exit " << endl;
161+
}
162+
);
163+
#if 0
137164
QThread::connect(
138165
this, &ClientSocket_Qt::send,
139166
&socket, [this](void* params){
@@ -165,6 +192,7 @@ class ClientSocket_Qt final : public QThread, public AbstractClientSocket{
165192
// cout << "internal_send() - exit " << endl;
166193
}
167194
);
195+
#endif
168196

169197

170198
{

Common/Cpp/Sockets/ClientSocket_WinSocket.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class ClientSocket_WinSocket final : public AbstractClientSocket{
6666
}
6767

6868

69-
virtual size_t blocking_send(const void* data, size_t bytes) override{
69+
virtual size_t send(const void* data, size_t bytes) override{
7070
if (m_socket == INVALID_SOCKET){
7171
return 0;
7272
}

SerialPrograms/Source/NintendoSwitch/Controllers/SysbotBase/SysbotBase_Connection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ ControllerModeStatus TcpSysbotBase_Connection::controller_mode_status() const{
111111
void TcpSysbotBase_Connection::write_data(const std::string& data){
112112
WriteSpinLock lg(m_send_lock, "TcpSysbotBase_Connection::write_data()");
113113
// cout << "Sending: " << data << endl;
114-
m_socket.blocking_send(data.data(), data.size());
114+
m_socket.send(data.data(), data.size());
115115
}
116116

117117

0 commit comments

Comments
 (0)