使用自定义模块脚本在艾泽拉斯核心世界进程中出现竞争条件的可能性

问题描述 投票:0回答:1

我正在使用此处理程序编写命令

.deposit $Character $moneyDelta
,以在角色离线时增加角色的金币。

    static bool HandleDepositCommand(ChatHandler *handler, PlayerIdentifier player, uint32 moneyDelta)
    {
        ObjectGuid::LowType accountId = player.GetGUID().GetCounter();

        // Player must not be in-game
        if (player.IsConnected()) {
            return false;
        }

        // The player should not log in until this function finishes execution
        // TODO SQL query to increase gold

        return true;
    }

为了确保引擎的缓存不会覆盖我的 SQL 写入,我强加了玩家不得登录的要求。

HandleDepositCommand()
执行完成之前,玩家是否可以连接?如果我理解正确的话,那么世界进程是一个单线程 while 循环,其中新的操作(例如新登录)在
HandleDepositCommand()
之后排队。

    ///- While we have not World::m_stopEvent, update the world
    while (!World::IsStopped())
    {
        ++World::m_worldLoopCounter;
        realCurrTime = getMSTime();

        uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime);
        if (diff < minUpdateDiff)
        {
            uint32 sleepTime = minUpdateDiff - diff;
            if (sleepTime >= halfMaxCoreStuckTime)
                LOG_ERROR("server.worldserver", "WorldUpdateLoop() waiting for {} ms with MaxCoreStuckTime set to {} ms", sleepTime, maxCoreStuckTime);
            // sleep until enough time passes that we can update all timers
            std::this_thread::sleep_for(Milliseconds(sleepTime));
            continue;
        }

        sWorld->Update(diff);
        realPrevTime = realCurrTime;

如果不是,那么这是一个可能导致漏洞利用的竞争条件。玩家在 SQL 完成之前登录会覆盖数据库状态。

c++ concurrency azerothcore world-of-warcraft trinitycore
1个回答
0
投票

不应该有任何竞争条件,因为聊天命令和玩家日志记录都具有“线程不安全”类型,这意味着它们在同一线程中运行。

© www.soinside.com 2019 - 2024. All rights reserved.