Skip to content

Commit

Permalink
fix: concurrent modification and casting in tile management
Browse files Browse the repository at this point in the history
Fixed issues related to concurrent modification of tile within safeCall by capturing the variable by reference. Added a null check for house to ensure safe usage. Updated the casting mechanism to improve robustness and avoid undefined behavior. These changes enhance thread safety and stability in the tile management system.
  • Loading branch information
dudantas committed Nov 12, 2024
1 parent 49c1540 commit a14dcc7
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/items/tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ class DynamicTile : public Tile {
CreatureVector creatures;

public:
DynamicTile(const Position &position) :
Tile(position.x, position.y, position.z) { }
DynamicTile(uint16_t x, uint16_t y, uint8_t z) :
Tile(x, y, z) { }

Expand Down Expand Up @@ -323,6 +325,8 @@ class StaticTile final : public Tile {
std::unique_ptr<CreatureVector> creatures;

public:
StaticTile(const Position &position) :
Tile(position.x, position.y, position.z) { }
StaticTile(uint16_t x, uint16_t y, uint8_t z) :
Tile(x, y, z) { }

Expand Down
3 changes: 3 additions & 0 deletions src/map/house/housetile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include "map/house/house.hpp"
#include "utils/tools.hpp"

HouseTile::HouseTile(const Position &position, std::shared_ptr<House> newHouse) :
DynamicTile(position.x, position.y, position.z), house(std::move(newHouse)) { }

HouseTile::HouseTile(int32_t initX, int32_t initY, int32_t initZ, std::shared_ptr<House> initHouse) :
DynamicTile(initX, initY, initZ), house(std::move(initHouse)) { }

Expand Down
1 change: 1 addition & 0 deletions src/map/house/housetile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class HouseTile final : public DynamicTile {
public:
using Tile::addThing;

HouseTile(const Position &position, std::shared_ptr<House> house);
HouseTile(int32_t x, int32_t y, int32_t z, std::shared_ptr<House> house);

// cylinder implementations
Expand Down
19 changes: 12 additions & 7 deletions src/map/mapcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,23 @@ std::shared_ptr<Tile> MapCache::getOrCreateTileFromCache(const std::shared_ptr<F

std::shared_ptr<Tile> tile = nullptr;

auto pos = Position(x, y, z);

if (cachedTile->isHouse()) {
const auto &house = map->houses.getHouse(cachedTile->houseId);
tile = std::make_shared<HouseTile>(x, y, z, house);
house->addTile(std::static_pointer_cast<HouseTile>(tile));
if (const auto &house = map->houses.getHouse(cachedTile->houseId)) {
tile = std::make_shared<HouseTile>(pos, house);
tile->safeCall([tile] {
tile->getHouse()->addTile(tile->static_self_cast<HouseTile>());
});
} else {
g_logger().error("[{}] house not found for houseId {}", std::source_location::current().function_name(), cachedTile->houseId);
}
} else if (cachedTile->isStatic) {
tile = std::make_shared<StaticTile>(x, y, z);
tile = std::make_shared<StaticTile>(pos);
} else {
tile = std::make_shared<DynamicTile>(x, y, z);
tile = std::make_shared<DynamicTile>(pos);
}

auto pos = Position(x, y, z);

for (const auto &creature : oldCreatureList) {
tile->internalAddThing(creature);
}
Expand Down

0 comments on commit a14dcc7

Please sign in to comment.