Skip to content

Commit

Permalink
Merge pull request #10624 from jackpoz/instancesavemgr
Browse files Browse the repository at this point in the history
Core/Instances: Fix mutex released after being deleted
  • Loading branch information
Machiavell1 committed Aug 25, 2013
2 parents eeb2102 + a3bdf90 commit 39ccd4a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/server/game/Instances/InstanceSaveMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,14 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId)
CharacterDatabase.Execute(stmt);
}

delete itr->second;
itr->second->SetToDelete(true);
m_instanceSaveById.erase(itr);
}
}

InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset)
: m_resetTime(resetTime), m_instanceid(InstanceId), m_mapid(MapId),
m_difficulty(difficulty), m_canReset(canReset)
m_difficulty(difficulty), m_canReset(canReset), m_toDelete(false)
{
}

Expand Down
30 changes: 28 additions & 2 deletions src/server/game/Instances/InstanceSaveMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,29 @@ class InstanceSave
/* online players bound to the instance (perm/solo)
does not include the members of the group unless they have permanent saves */
void AddPlayer(Player* player) { TRINITY_GUARD(ACE_Thread_Mutex, _lock); m_playerList.push_back(player); }
bool RemovePlayer(Player* player) { TRINITY_GUARD(ACE_Thread_Mutex, _lock); m_playerList.remove(player); return UnloadIfEmpty(); }
bool RemovePlayer(Player* player)
{
_lock.acquire();
m_playerList.remove(player);
bool isStillValid = UnloadIfEmpty();
_lock.release();

//delete here if needed, after releasing the lock
if(m_toDelete)
delete this;

return isStillValid;
}
/* all groups bound to the instance */
void AddGroup(Group* group) { m_groupList.push_back(group); }
bool RemoveGroup(Group* group) { m_groupList.remove(group); return UnloadIfEmpty(); }
bool RemoveGroup(Group* group)
{
m_groupList.remove(group);
bool isStillValid = UnloadIfEmpty();
if(m_toDelete)
delete this;
return isStillValid;
}

/* instances cannot be reset (except at the global reset time)
if there are players permanently bound to it
Expand All @@ -96,6 +115,12 @@ class InstanceSave
but that would depend on a lot of things that can easily change in future */
Difficulty GetDifficulty() const { return m_difficulty; }

/* used to flag the InstanceSave as to be deleted, so the caller can delete it */
void SetToDelete(bool toDelete)
{
m_toDelete = toDelete;
}

typedef std::list<Player*> PlayerListType;
typedef std::list<Group*> GroupListType;
private:
Expand All @@ -110,6 +135,7 @@ class InstanceSave
uint32 m_mapid;
Difficulty m_difficulty;
bool m_canReset;
bool m_toDelete;

ACE_Thread_Mutex _lock;
};
Expand Down

0 comments on commit 39ccd4a

Please sign in to comment.