wesnothd: exception safety fix
This fixes crash in response to server_shutdown exception getting thrown, as well as any other exception, that happens if there are any players logged on.
This commit is contained in:
parent
bfa16ee0c7
commit
ab97a37394
2 changed files with 30 additions and 21 deletions
|
@ -1069,7 +1069,9 @@ template<class SocketPtr> void server::handle_player(boost::asio::yield_context
|
|||
assert(inserted);
|
||||
|
||||
BOOST_SCOPE_EXIT_ALL(this, &player) {
|
||||
remove_player(player);
|
||||
if(!destructed) {
|
||||
remove_player(player);
|
||||
}
|
||||
};
|
||||
|
||||
async_send_doc_queued(socket, games_and_users_list_);
|
||||
|
@ -1368,7 +1370,7 @@ void server::cleanup_game(game* game_ptr)
|
|||
|
||||
// Send a diff of the gamelist with the game deleted to players in the lobby
|
||||
simple_wml::document diff;
|
||||
if(make_delete_diff(*gamelist, "gamelist", "game", game_ptr->description(), diff)) {
|
||||
if(!destructed && make_delete_diff(*gamelist, "gamelist", "game", game_ptr->description(), diff)) {
|
||||
send_to_lobby(diff);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,13 @@ class server : public server_base
|
|||
public:
|
||||
server(int port, bool keep_alive, const std::string& config_file, std::size_t, std::size_t);
|
||||
|
||||
// We keep this flag for coroutines. Since they get their stack unwinding done after player_connections_
|
||||
// is already destroyed they need to know to avoid calling remove_player() on invalid iterators.
|
||||
bool destructed = false;
|
||||
~server() {
|
||||
destructed = true;
|
||||
}
|
||||
|
||||
private:
|
||||
void handle_new_client(socket_ptr socket);
|
||||
void handle_new_client(tls_socket_ptr socket);
|
||||
|
@ -118,25 +125,6 @@ private:
|
|||
|
||||
std::mt19937 die_;
|
||||
|
||||
player_connections player_connections_;
|
||||
|
||||
std::deque<std::shared_ptr<game>> games() const
|
||||
{
|
||||
std::deque<std::shared_ptr<game>> result;
|
||||
|
||||
for(const auto& iter : player_connections_.get<game_t>()) {
|
||||
if(result.empty() || iter.get_game() != result.back()) {
|
||||
result.push_back(iter.get_game());
|
||||
}
|
||||
}
|
||||
|
||||
if(!result.empty() && result.front() == nullptr) {
|
||||
result.pop_front();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/** server socket/fifo. */
|
||||
std::string input_path_;
|
||||
|
@ -192,6 +180,25 @@ private:
|
|||
|
||||
metrics metrics_;
|
||||
|
||||
player_connections player_connections_;
|
||||
|
||||
std::deque<std::shared_ptr<game>> games() const
|
||||
{
|
||||
std::deque<std::shared_ptr<game>> result;
|
||||
|
||||
for(const auto& iter : player_connections_.get<game_t>()) {
|
||||
if(result.empty() || iter.get_game() != result.back()) {
|
||||
result.push_back(iter.get_game());
|
||||
}
|
||||
}
|
||||
|
||||
if(!result.empty() && result.front() == nullptr) {
|
||||
result.pop_front();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
boost::asio::steady_timer dump_stats_timer_;
|
||||
void start_dump_stats();
|
||||
void dump_stats(const boost::system::error_code& ec);
|
||||
|
|
Loading…
Add table
Reference in a new issue