Skip to content

Commit b3bb5e5

Browse files
Deal with Py_None getting incref'ed before the GIL is created.
1 parent ad7e962 commit b3bb5e5

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

Objects/typeobject.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ type_cache_clear(struct type_cache *cache, PyObject *value)
309309
void
310310
_PyType_InitCache(PyInterpreterState *interp)
311311
{
312+
int is_main = _Py_IsMainInterpreter(interp);
312313
struct type_cache *cache = &interp->types.type_cache;
313314
for (Py_ssize_t i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
314315
struct type_cache_entry *entry = &cache->hashtable[i];
@@ -317,11 +318,27 @@ _PyType_InitCache(PyInterpreterState *interp)
317318
entry->version = 0;
318319
// Set to None so _PyType_Lookup() can use Py_SETREF(),
319320
// rather than using slower Py_XSETREF().
320-
entry->name = Py_NewRef(Py_None);
321+
entry->name = Py_None;
322+
// Currently, this happens before the GIL has been created,
323+
// which is a problem without "immortality" (PEP 683).
324+
// Until we have immortal objects, we must avoid an INCREF
325+
// in the main interpreter here. Instead, we fix the refcount
326+
// in the main interpreer as soon as the GIL has been created.
327+
// (See pycore_create_interpreter() in pylifecycle.c.)
328+
if (!is_main) {
329+
Py_INCREF(Py_None);
330+
}
321331
entry->value = NULL;
322332
}
323333
}
324334

335+
// This is the temporary fix used by pycore_create_interpreter().
336+
void
337+
_PyType_FixCacheRefcounts(void)
338+
{
339+
_Py_RefcntAdd(Py_None, (1 << MCACHE_SIZE_EXP));
340+
}
341+
325342

326343
static unsigned int
327344
_PyType_ClearCache(PyInterpreterState *interp)

Python/pylifecycle.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,11 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
635635
return status;
636636
}
637637

638+
// This is a temporary fix until we have immortal objects.
639+
// (See _PyType_InitCache() in typeobject.c.)
640+
extern void _PyType_FixCacheRefcounts(void);
641+
_PyType_FixCacheRefcounts();
642+
638643
*tstate_p = tstate;
639644
return _PyStatus_OK();
640645
}

0 commit comments

Comments
 (0)