Destroy client, network sockets and other objects on shutdown.

merge-requests/50/head
Mr_Goldberg 2022-08-10 03:24:29 -04:00
parent 04022c005f
commit 7163daa6c1
No known key found for this signature in database
GPG Key ID: 8597D87419DEF278
4 changed files with 109 additions and 29 deletions

View File

@ -128,13 +128,26 @@ STEAMAPI_API ISteamClient *g_pSteamClientGameServer;
ISteamClient *g_pSteamClientGameServer; ISteamClient *g_pSteamClientGameServer;
#endif #endif
static Steam_Client *client;
Steam_Client *get_steam_client() Steam_Client *get_steam_client()
{ {
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
static Steam_Client *client = new Steam_Client(); if (!client) {
client = new Steam_Client();
}
return client; return client;
} }
void destroy_client()
{
std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (client) {
delete client;
client = NULL;
}
}
Steam_Client *get_steam_client_old() Steam_Client *get_steam_client_old()
{ {
return get_steam_client(); return get_steam_client();
@ -298,6 +311,9 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_Shutdown()
old_video_instance = NULL; old_video_instance = NULL;
old_parental_instance = NULL; old_parental_instance = NULL;
old_unified_instance = NULL; old_unified_instance = NULL;
if (global_counter == 0) {
destroy_client();
}
} }
// SteamAPI_RestartAppIfNecessary ensures that your executable was launched through Steam. // SteamAPI_RestartAppIfNecessary ensures that your executable was launched through Steam.
@ -607,11 +623,14 @@ STEAMAPI_API ISteamClient *SteamGameServerClient();
STEAMAPI_API steam_bool S_CALLTYPE SteamInternal_GameServer_Init( uint32 unIP, uint16 usPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ) STEAMAPI_API steam_bool S_CALLTYPE SteamInternal_GameServer_Init( uint32 unIP, uint16 usPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString )
{ {
PRINT_DEBUG("SteamInternal_GameServer_Init %u %hu %hu %hu %u %s\n", unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString); PRINT_DEBUG("SteamInternal_GameServer_Init %u %hu %hu %hu %u %s\n", unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString);
if (!server_steam_pipe) {
load_old_interface_versions(); load_old_interface_versions();
get_steam_client()->CreateLocalUser(&server_steam_pipe, k_EAccountTypeGameServer); get_steam_client()->CreateLocalUser(&server_steam_pipe, k_EAccountTypeGameServer);
++global_counter; ++global_counter;
//g_pSteamClientGameServer is only used in pre 1.37 (where the interface versions are not provided by the game) //g_pSteamClientGameServer is only used in pre 1.37 (where the interface versions are not provided by the game)
g_pSteamClientGameServer = SteamGameServerClient(); g_pSteamClientGameServer = SteamGameServerClient();
}
uint32 unFlags = 0; uint32 unFlags = 0;
if (eServerMode == eServerModeAuthenticationAndSecure) unFlags = k_unServerFlagSecure; if (eServerMode == eServerModeAuthenticationAndSecure) unFlags = k_unServerFlagSecure;
return get_steam_client()->steam_gameserver->InitGameServer(unIP, usGamePort, usQueryPort, unFlags, 0, pchVersionString); return get_steam_client()->steam_gameserver->InitGameServer(unIP, usGamePort, usQueryPort, unFlags, 0, pchVersionString);
@ -678,6 +697,10 @@ STEAMAPI_API void SteamGameServer_Shutdown()
old_gamserver_ugc_instance = NULL; old_gamserver_ugc_instance = NULL;
old_gamserver_apps_instance = NULL; old_gamserver_apps_instance = NULL;
old_gamserver_masterupdater_instance = NULL; old_gamserver_masterupdater_instance = NULL;
if (global_counter == 0) {
destroy_client();
}
} }
STEAMAPI_API void SteamGameServer_RunCallbacks() STEAMAPI_API void SteamGameServer_RunCallbacks()

View File

@ -751,7 +751,6 @@ Networking::Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT>
{ {
tcp_port = udp_port = port; tcp_port = udp_port = port;
own_ip = 0x7F000001; own_ip = 0x7F000001;
alive = true;
last_run = std::chrono::high_resolution_clock::now(); last_run = std::chrono::high_resolution_clock::now();
this->appid = appid; this->appid = appid;
@ -843,6 +842,21 @@ Networking::Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT>
reset_last_error(); reset_last_error();
} }
Networking::~Networking()
{
for (auto &c : connections) {
kill_tcp_socket(c.tcp_socket_incoming);
kill_tcp_socket(c.tcp_socket_outgoing);
}
for (auto &c : accepted) {
kill_tcp_socket(c);
}
kill_socket(udp_socket);
kill_socket(tcp_socket);
}
Common_Message Networking::create_announce(bool request) Common_Message Networking::create_announce(bool request)
{ {
Announce *announce = new Announce(); Announce *announce = new Announce();
@ -1265,13 +1279,3 @@ uint32 Networking::getOwnIP()
{ {
return own_ip; return own_ip;
} }
void Networking::shutDown()
{
alive = false;
}
bool Networking::isAlive()
{
return alive;
}

View File

@ -90,7 +90,6 @@ struct Connection {
class Networking { class Networking {
bool enabled = false; bool enabled = false;
bool alive;
std::chrono::high_resolution_clock::time_point last_run; std::chrono::high_resolution_clock::time_point last_run;
sock_t udp_socket, tcp_socket; sock_t udp_socket, tcp_socket;
uint16 udp_port, tcp_port; uint16 udp_port, tcp_port;
@ -126,6 +125,7 @@ public:
//ex: 127.0.0.1 should be passed as 0x7F000001 //ex: 127.0.0.1 should be passed as 0x7F000001
static std::set<IP_PORT> resolve_ip(std::string dns); static std::set<IP_PORT> resolve_ip(std::string dns);
Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT> *custom_broadcasts, bool disable_sockets); Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT> *custom_broadcasts, bool disable_sockets);
~Networking();
void addListenId(CSteamID id); void addListenId(CSteamID id);
void setAppID(uint32 appid); void setAppID(uint32 appid);
void Run(); void Run();
@ -137,9 +137,6 @@ public:
bool setCallback(Callback_Ids id, CSteamID steam_id, void (*message_callback)(void *object, Common_Message *msg), void *object); bool setCallback(Callback_Ids id, CSteamID steam_id, void (*message_callback)(void *object, Common_Message *msg), void *object);
uint32 getIP(CSteamID id); uint32 getIP(CSteamID id);
uint32 getOwnIP(); uint32 getOwnIP();
void shutDown();
bool isAlive();
}; };
#endif #endif

View File

@ -18,21 +18,23 @@
#include "steam_client.h" #include "steam_client.h"
#include "settings_parser.h" #include "settings_parser.h"
static std::mutex kill_background_thread_mutex;
static std::condition_variable kill_background_thread_cv; static std::condition_variable kill_background_thread_cv;
static std::atomic_bool kill_background_thread; static bool kill_background_thread;
static void background_thread(Steam_Client *client) static void background_thread(Steam_Client *client)
{ {
PRINT_DEBUG("background thread starting\n"); PRINT_DEBUG("background thread starting\n");
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while (1) { while (1) {
{
std::unique_lock<std::mutex> lck(kill_background_thread_mutex);
if (kill_background_thread || kill_background_thread_cv.wait_for(lck, std::chrono::seconds(1)) != std::cv_status::timeout) { if (kill_background_thread || kill_background_thread_cv.wait_for(lck, std::chrono::seconds(1)) != std::cv_status::timeout) {
if (kill_background_thread) { if (kill_background_thread) {
PRINT_DEBUG("background thread exit\n"); PRINT_DEBUG("background thread exit\n");
return; return;
} }
} }
}
unsigned long long time = std::chrono::duration_cast<std::chrono::duration<unsigned long long>>(std::chrono::system_clock::now().time_since_epoch()).count(); unsigned long long time = std::chrono::duration_cast<std::chrono::duration<unsigned long long>>(std::chrono::system_clock::now().time_since_epoch()).count();
@ -122,7 +124,59 @@ Steam_Client::Steam_Client()
Steam_Client::~Steam_Client() Steam_Client::~Steam_Client()
{ {
network->shutDown(); delete steam_gameserver;
delete steam_gameserver_utils;
delete steam_gameserverstats;
delete steam_gameserver_networking;
delete steam_gameserver_http;
delete steam_gameserver_inventory;
delete steam_gameserver_ugc;
delete steam_gameserver_apps;
delete steam_gameserver_networking_sockets;
delete steam_gameserver_networking_sockets_serialized;
delete steam_gameserver_networking_messages;
delete steam_gameserver_game_coordinator;
delete steam_masterserver_updater;
delete steam_matchmaking;
delete steam_matchmaking_servers;
delete steam_user_stats;
delete steam_apps;
delete steam_networking;
delete steam_remote_storage;
delete steam_screenshots;
delete steam_http;
delete steam_controller;
delete steam_ugc;
delete steam_applist;
delete steam_music;
delete steam_musicremote;
delete steam_HTMLsurface;
delete steam_inventory;
delete steam_video;
delete steam_parental;
delete steam_networking_sockets;
delete steam_networking_sockets_serialized;
delete steam_networking_messages;
delete steam_game_coordinator;
delete steam_networking_utils;
delete steam_unified_messages;
delete steam_game_search;
delete steam_parties;
delete steam_remoteplay;
delete steam_tv;
delete steam_utils;
delete steam_friends;
delete steam_user;
delete steam_overlay;
delete run_every_runcb;
delete callbacks_server;
delete callbacks_client;
delete callback_results_server;
delete callback_results_client;
delete network;
} }
void Steam_Client::userLogIn() void Steam_Client::userLogIn()
@ -825,7 +879,9 @@ bool Steam_Client::BShutdownIfAllPipesClosed()
if (!steam_pipes.size()) { if (!steam_pipes.size()) {
bool joinable = background_keepalive.joinable(); bool joinable = background_keepalive.joinable();
if (joinable) { if (joinable) {
kill_background_thread_mutex.lock();
kill_background_thread = true; kill_background_thread = true;
kill_background_thread_mutex.unlock();
kill_background_thread_cv.notify_one(); kill_background_thread_cv.notify_one();
} }