|
1 | 1 | using System; |
2 | | -using System.Collections.Generic; |
3 | | -using System.Runtime.InteropServices; |
| 2 | +using System.Collections.Concurrent; |
4 | 3 |
|
5 | 4 | namespace Python.Runtime |
6 | 5 | { |
@@ -37,6 +36,11 @@ def find_spec(klass, fullname, paths=None, target=None): |
37 | 36 | if 'clr' not in sys.modules: |
38 | 37 | return None |
39 | 38 | clr = sys.modules['clr'] |
| 39 | +
|
| 40 | + _add_pending = clr._add_pending_namespaces |
| 41 | + if _add_pending: |
| 42 | + _add_pending() |
| 43 | +
|
40 | 44 | if clr._available_namespaces and fullname in clr._available_namespaces: |
41 | 45 | return importlib.machinery.ModuleSpec(fullname, DotNetLoader(), is_package=True) |
42 | 46 | return None |
@@ -169,12 +173,26 @@ static void TeardownNameSpaceTracking() |
169 | 173 | Runtime.PyDict_SetItemString(root.dict, availableNsKey, Runtime.PyNone); |
170 | 174 | } |
171 | 175 |
|
172 | | - public static void AddNamespace(string name) |
| 176 | + static readonly ConcurrentQueue<string> addPending = new(); |
| 177 | + public static void AddNamespace(string name) => addPending.Enqueue(name); |
| 178 | + |
| 179 | + internal static int AddPendingNamespaces() |
| 180 | + { |
| 181 | + int added = 0; |
| 182 | + while (addPending.TryDequeue(out string ns)) |
| 183 | + { |
| 184 | + AddNamespaceWithGIL(ns); |
| 185 | + added++; |
| 186 | + } |
| 187 | + return added; |
| 188 | + } |
| 189 | + |
| 190 | + internal static void AddNamespaceWithGIL(string name) |
173 | 191 | { |
174 | 192 | var pyNs = Runtime.PyString_FromString(name); |
175 | 193 | try |
176 | 194 | { |
177 | | - var nsSet = Runtime.PyDict_GetItemString(new BorrowedReference(root.dict), availableNsKey); |
| 195 | + var nsSet = Runtime.PyDict_GetItemString(root.DictRef, availableNsKey); |
178 | 196 | if (!(nsSet.IsNull || nsSet.DangerousGetAddress() == Runtime.PyNone)) |
179 | 197 | { |
180 | 198 | if (Runtime.PySet_Add(nsSet, new BorrowedReference(pyNs)) != 0) |
|
0 commit comments