bpo-29102: Add a unique ID to PyInterpreterState. (#1639)

This commit is contained in:
Eric Snow 2017-05-22 19:46:40 -07:00 committed by GitHub
parent 93fc20b73e
commit e377416c10
8 changed files with 152 additions and 7 deletions

View file

@ -65,6 +65,23 @@ PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
static void _PyGILState_NoteThreadState(PyThreadState* tstate);
#endif
/* _next_interp_id is an auto-numbered sequence of small integers.
It gets initialized in _PyInterpreterState_Init(), which is called
in Py_Initialize(), and used in PyInterpreterState_New(). A negative
interpreter ID indicates an error occurred. The main interpreter
will always have an ID of 0. Overflow results in a RuntimeError.
If that becomes a problem later then we can adjust, e.g. by using
a Python int.
We initialize this to -1 so that the pre-Py_Initialize() value
results in an error. */
static int64_t _next_interp_id = -1;
void
_PyInterpreterState_Init(void)
{
_next_interp_id = 0;
}
PyInterpreterState *
PyInterpreterState_New(void)
@ -103,6 +120,15 @@ PyInterpreterState_New(void)
HEAD_LOCK();
interp->next = interp_head;
interp_head = interp;
if (_next_interp_id < 0) {
/* overflow or Py_Initialize() not called! */
PyErr_SetString(PyExc_RuntimeError,
"failed to get an interpreter ID");
interp = NULL;
} else {
interp->id = _next_interp_id;
_next_interp_id += 1;
}
HEAD_UNLOCK();
}
@ -170,6 +196,17 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
}
int64_t
PyInterpreterState_GetID(PyInterpreterState *interp)
{
if (interp == NULL) {
PyErr_SetString(PyExc_RuntimeError, "no interpreter provided");
return -1;
}
return interp->id;
}
/* Default implementation for _PyThreadState_GetFrame */
static struct _frame *
threadstate_getframe(PyThreadState *self)