Skip to content
This repository was archived by the owner on Jan 22, 2026. It is now read-only.

Commit 7e107ef

Browse files
committed
XMLBuilderDomain: Lock global xml_refs dict
Otherwise a threaded app like virt-manager can cause problems (which we've had reports of, like 'dictionary changed size during iteration'
1 parent 2151b04 commit 7e107ef

1 file changed

Lines changed: 30 additions & 16 deletions

File tree

virtinst/XMLBuilderDomain.py

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
# MA 02110-1301 USA.
2121

2222
import copy
23+
import threading
2324

2425
import libvirt
2526
import libxml2
@@ -28,36 +29,49 @@
2829
import _util
2930
from virtinst import _gettext as _
3031

32+
_xml_refs_lock = threading.Lock()
3133
_xml_refs = {}
34+
3235
def _unref_doc(doc):
3336
if not doc:
3437
return
3538

3639
idx = None
37-
for n in _xml_refs:
38-
if n == doc:
39-
idx = n
40-
break
4140

42-
if not idx:
43-
return
41+
try:
42+
_xml_refs_lock.acquire()
43+
44+
for n in _xml_refs:
45+
if n == doc:
46+
idx = n
47+
break
4448

45-
_xml_refs[idx] = _xml_refs[idx] - 1
46-
if _xml_refs[idx] == 0:
47-
idx.freeDoc()
49+
if not idx:
50+
return
51+
52+
_xml_refs[idx] = _xml_refs[idx] - 1
53+
if _xml_refs[idx] == 0:
54+
idx.freeDoc()
55+
finally:
56+
_xml_refs_lock.release()
4857

4958
def _ref_doc(doc):
5059
if not doc:
5160
return
5261

53-
idx = doc
54-
for n in _xml_refs:
55-
if n == doc:
56-
idx = n
57-
break
62+
try:
63+
_xml_refs_lock.acquire()
64+
65+
idx = doc
66+
for n in _xml_refs:
67+
if n == doc:
68+
idx = n
69+
break
5870

59-
refcount = _xml_refs.get(idx) or 0
60-
_xml_refs[idx] = refcount + 1
71+
refcount = _xml_refs.get(idx) or 0
72+
_xml_refs[idx] = refcount + 1
73+
finally:
74+
_xml_refs_lock.release()
6175

6276
def _sanitize_libxml_xml(xml):
6377
# Strip starting <?...> line

0 commit comments

Comments
 (0)