Inventory enumeration race condition requires a general fix

Issue #118 open
Hurcan Solter created an issue

As per title use poison, skill while iterating the items in the inventory only visit the backpack once

               for (it=FirstInv();it;it=NextInv())
                  if (it->HasStati(POISONED) && it->iID == vialID)
                    { found = true;
                      thisp->MyTerm->LOption(it->Name(NA_LONG),it->myHandle); }
                if (!found)
                  { IPrint("You have no poisons to apply.");
                    return; }

NextInv() returns null after finding the first vial. this works with other consumables though since they are handled differently.

Comments (9)

  1. RMTEW FULL NAME repo owner

    This will be fixed in the next release. I've also discovered the inventory problem for another bug, and will be replacing all inventory access with a method that doesn't have thos problem.

  2. Hurcan Solter reporter

    I've noticed the Item::Name() throws an event that causes the inventory to be enumerated again thus making the iterator in the above loop point to the end. Maybe convert inventory to an std like container so multiple iterators can work on it as long as the inventory is not modified.

  3. RMTEW FULL NAME repo owner

    I've refrained from fixing this, because it is not possible to fix in all cases. The scripting language also calls these functions, and is prone to the same error, and it does not support either your approach or my own.

  4. RMTEW FULL NAME repo owner

    Issue #157 needs to be fixed at the same time. That issue requires that the new inventory enumeration allow filtering out the contents of locked containers. And perhaps even be done in a generic way that can handle additional filtering constraints.

  5. Log in to comment