Inventory enumeration race condition requires a general fix
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)
-
reporter -
reporter - attached Wode.sav
here the attached save file.
-
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.
-
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.
-
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.
-
repo owner -
assigned issue to
- changed title to Inventory enumeration race condition requires a general fix
The main problem remaining with fixing this, is that scripts have a limited subset of C++ available to them, and cannot make use of any solutions where state is extracted to the local context.
-
assigned issue to
-
repo owner - changed status to open
-
repo owner Issue
#154was marked as a duplicate of this issue. -
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.
- Log in to comment
Hmm, does not happen with a new save. I'll upload the erroneous save later on.