Fix race between network client disconnect and network window deletion

pull/400/head
Jonathan G Rennison 2 years ago
parent ccef4baea6
commit ff064e06b8

@ -15,6 +15,7 @@
#include "../network_internal.h"
#include "../../debug.h"
#include "../../error.h"
#include "../../window_func.h"
#include "table/strings.h"
@ -109,6 +110,7 @@ NetworkRecvStatus NetworkGameSocketHandler::CloseConnection(bool error)
if (!_network_server && _networking) {
extern void ClientNetworkEmergencySave(); // from network_client.cpp
ClientNetworkEmergencySave();
DeleteNetworkClientWindows();
_switch_mode = SM_MENU;
_networking = false;
ShowErrorMessage(STR_NETWORK_ERROR_LOSTCONNECTION, INVALID_STRING_ID, WL_CRITICAL);

@ -522,7 +522,7 @@ static const NWidgetPart _nested_chat_window_widgets[] = {
static WindowDesc _chat_window_desc(
WDP_MANUAL, nullptr, 0, 0,
WC_SEND_NETWORK_MSG, WC_NONE,
0,
WDF_NETWORK,
_nested_chat_window_widgets, lengthof(_nested_chat_window_widgets)
);

@ -257,6 +257,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
ClientNetworkEmergencySave();
}
DeleteNetworkClientWindows();
_switch_mode = SM_MENU;
_networking = false;
}

@ -1016,7 +1016,7 @@ static const NWidgetPart _nested_network_game_widgets[] = {
static WindowDesc _network_game_window_desc(
WDP_CENTER, "list_servers", 1000, 730,
WC_NETWORK_WINDOW, WC_NONE,
0,
WDF_NETWORK,
_nested_network_game_widgets, lengthof(_nested_network_game_widgets)
);
@ -1289,7 +1289,7 @@ static const NWidgetPart _nested_network_start_server_window_widgets[] = {
static WindowDesc _network_start_server_window_desc(
WDP_CENTER, nullptr, 0, 0,
WC_NETWORK_WINDOW, WC_NONE,
0,
WDF_NETWORK,
_nested_network_start_server_window_widgets, lengthof(_nested_network_start_server_window_widgets)
);
@ -1366,7 +1366,7 @@ static const NWidgetPart _nested_client_list_widgets[] = {
static WindowDesc _client_list_desc(
WDP_AUTO, "list_clients", 220, 300,
WC_CLIENT_LIST, WC_NONE,
0,
WDF_NETWORK,
_nested_client_list_widgets, lengthof(_nested_client_list_widgets)
);
@ -2259,7 +2259,7 @@ static const NWidgetPart _nested_network_join_status_window_widgets[] = {
static WindowDesc _network_join_status_window_desc(
WDP_CENTER, nullptr, 0, 0,
WC_NETWORK_STATUS_WINDOW, WC_NONE,
WDF_MODAL,
WDF_MODAL | WDF_NETWORK,
_nested_network_join_status_window_widgets, lengthof(_nested_network_join_status_window_widgets)
);
@ -2382,7 +2382,7 @@ static const NWidgetPart _nested_network_company_password_window_widgets[] = {
static WindowDesc _network_company_password_window_desc(
WDP_AUTO, nullptr, 0, 0,
WC_COMPANY_PASSWORD_WINDOW, WC_NONE,
0,
WDF_NETWORK,
_nested_network_company_password_window_widgets, lengthof(_nested_network_company_password_window_widgets)
);
@ -2484,7 +2484,7 @@ static const NWidgetPart _nested_network_ask_relay_widgets[] = {
static WindowDesc _network_ask_relay_desc(
WDP_CENTER, nullptr, 0, 0,
WC_NETWORK_ASK_RELAY, WC_NONE,
WDF_MODAL,
WDF_MODAL | WDF_NETWORK,
_nested_network_ask_relay_widgets, lengthof(_nested_network_ask_relay_widgets)
);

@ -3510,6 +3510,19 @@ void DeleteConstructionWindows()
}
}
/**
* Delete all windows that use network client functionality.
*/
void DeleteNetworkClientWindows()
{
/* Note: the container remains stable, even when deleting windows. */
for (const Window *w : Window::IterateUnordered()) {
if (w->window_desc->flags & WDF_NETWORK) {
delete w;
}
}
}
/** Delete all always on-top windows to get an empty screen */
void HideVitalWindows()
{

@ -40,6 +40,7 @@ void DeleteNonVitalWindows();
void DeleteAllNonVitalWindows();
void DeleteAllMessages();
void DeleteConstructionWindows();
void DeleteNetworkClientWindows();
void HideVitalWindows();
void ShowVitalWindows();

@ -229,6 +229,7 @@ enum WindowDefaultFlag {
WDF_CONSTRUCTION = 1 << 0, ///< This window is used for construction; close it whenever changing company.
WDF_MODAL = 1 << 1, ///< The window is a modal child of some other window, meaning the parent is 'inactive'
WDF_NO_FOCUS = 1 << 2, ///< This window won't get focus/make any other window lose focus when click
WDF_NETWORK = 1 << 3, ///< This window is used for network client functionality
};
/**

Loading…
Cancel
Save