Improved disconnect handling in ASyncDBConnectionThread

This commit is contained in:
eelke 2025-02-25 17:55:53 +01:00
parent a5069bb2b9
commit 3c943b1503

View file

@ -81,7 +81,7 @@ private:
void doStateCallback(ASyncDBConnection::StateData state); void doStateCallback(ASyncDBConnection::StateData state);
/// Wait's for a command to come in and send's it to the server /// Wait's for a command to come in and send's it to the server
void waitForAndSendCommand(); bool waitForAndSendCommand();
void doNewCommand(); void doNewCommand();
void waitForResult(); void waitForResult();
@ -236,7 +236,9 @@ void ASyncDBConnectionThread::communicate()
if (m_state == ASyncDBConnection::State::Connected) { if (m_state == ASyncDBConnection::State::Connected) {
waitForAndSendCommand(); if (!waitForAndSendCommand()) {
return;
}
} }
else if (m_state == ASyncDBConnection::State::QuerySend || m_state == ASyncDBConnection::State::CancelSend) { else if (m_state == ASyncDBConnection::State::QuerySend || m_state == ASyncDBConnection::State::CancelSend) {
// Wait for result, even after a cancel we should wait, for all results // Wait for result, even after a cancel we should wait, for all results
@ -255,14 +257,21 @@ void ASyncDBConnectionThread::stop()
void ASyncDBConnectionThread::doStateCallback(ASyncDBConnection::StateData state) void ASyncDBConnectionThread::doStateCallback(ASyncDBConnection::StateData state)
{ {
qDebug() << "State change " + state.Message;
m_state = state.State; m_state = state.State;
Q_EMIT asyncConnObject->onStateChanged(state); Q_EMIT asyncConnObject->onStateChanged(state);
} }
void ASyncDBConnectionThread::waitForAndSendCommand() bool ASyncDBConnectionThread::waitForAndSendCommand()
{ {
SOCKET sock = static_cast<SOCKET>(m_connection.socket());
Win32Event socket_event(Win32Event::Reset::Manual, Win32Event::Initial::Clear);
long fd = FD_READ | FD_CLOSE;
WSAEventSelect(sock, socket_event.handle(), fd);
WaitHandleList whl; WaitHandleList whl;
auto wait_result_new_command = whl.add(m_commandQueue.m_newEvent); auto wait_result_new_command = whl.add(m_commandQueue.m_newEvent);
auto wait_result_socket = whl.add(socket_event);
whl.add(m_stopEvent); whl.add(m_stopEvent);
DWORD res = MsgWaitForMultipleObjectsEx( DWORD res = MsgWaitForMultipleObjectsEx(
@ -275,8 +284,17 @@ void ASyncDBConnectionThread::waitForAndSendCommand()
if (res == wait_result_new_command) { if (res == wait_result_new_command) {
doNewCommand(); doNewCommand();
} }
else if (res == wait_result_socket) {
WSANETWORKEVENTS net_events;
WSAEnumNetworkEvents(sock, socket_event.handle(), &net_events);
if (net_events.lNetworkEvents & FD_CLOSE) {
doStateCallback({ ASyncDBConnection::State::NotConnected, "Connection lost" });
return false;
}
}
// Note if it was stop we can just return and function // Note if it was stop we can just return and function
// above will stop looping because terminateRequested has been set too by stop // above will stop looping because terminateRequested has been set too by stop
return true;
} }
void ASyncDBConnectionThread::doNewCommand() void ASyncDBConnectionThread::doNewCommand()
@ -358,6 +376,11 @@ void ASyncDBConnectionThread::waitForResult()
finished = true; finished = true;
} }
} }
else if (net_events.lNetworkEvents & FD_CLOSE) {
doStateCallback({ ASyncDBConnection::State::NotConnected, "Close while waiting for result" });
finished = true;
stop();
}
} }
if (res == wait_result_stop) { if (res == wait_result_stop) {
// Send cancel, close connection and terminate thread // Send cancel, close connection and terminate thread