Add mutex lock to PythonObjectCache::lookup() - cache.find() was unprotected against concurrent modification. Document that entity.die() must not be called during iteration over grid.entities. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
115e16f4f2
commit
394e79ce88
2 changed files with 9 additions and 3 deletions
|
|
@ -37,7 +37,7 @@ void PythonObjectCache::registerObject(uint64_t serial, PyObject* weakref) {
|
||||||
PyObject* PythonObjectCache::lookup(uint64_t serial) {
|
PyObject* PythonObjectCache::lookup(uint64_t serial) {
|
||||||
if (serial == 0) return nullptr;
|
if (serial == 0) return nullptr;
|
||||||
|
|
||||||
// No mutex needed for read - GIL protects PyWeakref_GetRef
|
std::lock_guard<std::mutex> lock(serial_mutex);
|
||||||
auto it = cache.find(serial);
|
auto it = cache.find(serial);
|
||||||
if (it != cache.end()) {
|
if (it != cache.end()) {
|
||||||
PyObject* obj = nullptr;
|
PyObject* obj = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -926,7 +926,10 @@ PyMethodDef UIEntity::methods[] = {
|
||||||
" state = entity.at((5, 3))\n"
|
" state = entity.at((5, 3))\n"
|
||||||
" state = entity.at(pos=(5, 3))"},
|
" state = entity.at(pos=(5, 3))"},
|
||||||
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"},
|
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"},
|
||||||
{"die", (PyCFunction)UIEntity::die, METH_NOARGS, "Remove this entity from its grid"},
|
{"die", (PyCFunction)UIEntity::die, METH_NOARGS,
|
||||||
|
"Remove this entity from its grid.\n\n"
|
||||||
|
"Warning: Do not call during iteration over grid.entities.\n"
|
||||||
|
"Modifying the collection during iteration raises RuntimeError."},
|
||||||
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
|
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
|
||||||
"path_to(x, y) or path_to(target) -> list\n\n"
|
"path_to(x, y) or path_to(target) -> list\n\n"
|
||||||
"Find a path to the target position using Dijkstra pathfinding.\n\n"
|
"Find a path to the target position using Dijkstra pathfinding.\n\n"
|
||||||
|
|
@ -997,7 +1000,10 @@ PyMethodDef UIEntity_all_methods[] = {
|
||||||
" state = entity.at((5, 3))\n"
|
" state = entity.at((5, 3))\n"
|
||||||
" state = entity.at(pos=(5, 3))"},
|
" state = entity.at(pos=(5, 3))"},
|
||||||
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"},
|
{"index", (PyCFunction)UIEntity::index, METH_NOARGS, "Return the index of this entity in its grid's entity collection"},
|
||||||
{"die", (PyCFunction)UIEntity::die, METH_NOARGS, "Remove this entity from its grid"},
|
{"die", (PyCFunction)UIEntity::die, METH_NOARGS,
|
||||||
|
"Remove this entity from its grid.\n\n"
|
||||||
|
"Warning: Do not call during iteration over grid.entities.\n"
|
||||||
|
"Modifying the collection during iteration raises RuntimeError."},
|
||||||
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
|
{"path_to", (PyCFunction)UIEntity::path_to, METH_VARARGS | METH_KEYWORDS,
|
||||||
"path_to(x, y) or path_to(target) -> list\n\n"
|
"path_to(x, y) or path_to(target) -> list\n\n"
|
||||||
"Find a path to the target position using Dijkstra pathfinding.\n\n"
|
"Find a path to the target position using Dijkstra pathfinding.\n\n"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue