Skip to content

Commit

Permalink
Server: avoid re-use of recent ParticleSpawner and Sound IDs
Browse files Browse the repository at this point in the history
This improves the reliability when removing and re-adding handles quickly.
Looping through the entire ID range avoids collisions caused by any race condition.
  • Loading branch information
SmallJoker committed Nov 26, 2023
1 parent 6783734 commit 58a2ce3
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 16 deletions.
15 changes: 9 additions & 6 deletions src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2171,12 +2171,15 @@ void Server::SendPlayerSpeed(session_t peer_id, const v3f &added_vel)

inline s32 Server::nextSoundId()
{
s32 ret = m_next_sound_id;
if (m_next_sound_id == INT32_MAX)
m_next_sound_id = 0; // signed overflow is undefined
else
m_next_sound_id++;
return ret;
s32 free_id = m_playing_sounds_id_last_used;
while (free_id == 0 || m_playing_sounds.find(free_id) != m_playing_sounds.end()) {
if (free_id == INT32_MAX)
free_id = 0; // signed overflow is undefined
else
free_id++;
}
m_playing_sounds_id_last_used = free_id;
return free_id;
}

s32 Server::playSound(ServerPlayingSound &params, bool ephemeral)
Expand Down
2 changes: 1 addition & 1 deletion src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
Sounds
*/
std::unordered_map<s32, ServerPlayingSound> m_playing_sounds;
s32 m_next_sound_id = 0; // positive values only
s32 m_playing_sounds_id_last_used = 0; // positive values only
s32 nextSoundId();

ModStorageDatabase *m_mod_storage_database = nullptr;
Expand Down
18 changes: 9 additions & 9 deletions src/serverenvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,16 +1637,16 @@ u32 ServerEnvironment::addParticleSpawner(float exptime)
// Timers with lifetime 0 do not expire
float time = exptime > 0.f ? exptime : PARTICLE_SPAWNER_NO_EXPIRY;

u32 id = 0;
for (;;) { // look for unused particlespawner id
id++;
std::unordered_map<u32, float>::iterator f = m_particle_spawners.find(id);
if (f == m_particle_spawners.end()) {
m_particle_spawners[id] = time;
break;
}
u32 free_id = m_particle_spawners_id_last_used;
while (free_id == 0 || m_particle_spawners.find(free_id) != m_particle_spawners.end()) {
if (free_id == m_particle_spawners_id_last_used)
return 0; // full
free_id++;
}
return id;

m_particle_spawners_id_last_used = free_id;
m_particle_spawners[free_id] = time;
return free_id;
}

u32 ServerEnvironment::addParticleSpawner(float exptime, u16 attached_id)
Expand Down
1 change: 1 addition & 0 deletions src/serverenvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ class ServerEnvironment final : public Environment
// Particles
IntervalLimiter m_particle_management_interval;
std::unordered_map<u32, float> m_particle_spawners;
u32 m_particle_spawners_id_last_used = 0;
std::unordered_map<u32, u16> m_particle_spawner_attachments;

// Environment metrics
Expand Down

0 comments on commit 58a2ce3

Please sign in to comment.