Commit 44236598 authored by Guido van Rossum's avatar Guido van Rossum

- pythunrun.c, Py_Finalize(): move the call to _Py_PrintReferences()

  even farther down, to just before the call to
  _PyObject_DebugMallocStats().  This required the following changes:

- pystate.c, PyThreadState_GetDict(): changed not to raise an
  exception or issue a fatal error when no current thread state is
  available, but simply return NULL without raising an exception
  (ever).

- object.c, Py_ReprEnter(): when PyThreadState_GetDict() returns NULL,
  don't raise an exception but return 0.  This means that when
  printing a container that's recursive, printing will go on and on
  and on.  But that shouldn't happen in the case we care about (see
  first bullet).

- Updated Misc/NEWS and Doc/api/init.tex to reflect changes to
  PyThreadState_GetDict() definition.
parent ff921d05
......@@ -677,9 +677,12 @@ interpreter lock has been created.
\begin{cfuncdesc}{PyObject*}{PyThreadState_GetDict}{}
Return a dictionary in which extensions can store thread-specific
state information. Each extension should use a unique key to use to
store state in the dictionary. If this function returns \NULL, an
exception has been raised and the caller should allow it to
propagate.
store state in the dictionary. It is okay to call this function
when no current thread state is available.
If this function returns \NULL, no exception has been raised and the
caller should assume no current thread state is available.
\versionchanged[Previously this could only be called when a current
thread is active, and \NULL meant that an exception was raised]{2.3}
\end{cfuncdesc}
......
......@@ -150,6 +150,10 @@ Build
C API
-----
- PyThreadState_GetDict() was changed not to raise an exception or
issue a fatal error when no current thread state is available. This
makes it possible to print dictionaries when no thread is active.
- LONG_LONG was renamed to PY_LONG_LONG.
- Added PyObject_SelfIter() to fill the tp_iter slot for the
......
......@@ -2119,7 +2119,7 @@ Py_ReprEnter(PyObject *obj)
dict = PyThreadState_GetDict();
if (dict == NULL)
return -1;
return 0;
list = PyDict_GetItemString(dict, KEY);
if (list == NULL) {
list = PyList_New(0);
......
......@@ -266,17 +266,21 @@ PyThreadState_Swap(PyThreadState *new)
/* An extension mechanism to store arbitrary additional per-thread state.
PyThreadState_GetDict() returns a dictionary that can be used to hold such
state; the caller should pick a unique key and store its state there. If
PyThreadState_GetDict() returns NULL, an exception has been raised (most
likely MemoryError) and the caller should pass on the exception. */
PyThreadState_GetDict() returns NULL, an exception has *not* been raised
and the caller should assume no per-thread state is available. */
PyObject *
PyThreadState_GetDict(void)
{
if (_PyThreadState_Current == NULL)
Py_FatalError("PyThreadState_GetDict: no current thread");
return NULL;
if (_PyThreadState_Current->dict == NULL)
_PyThreadState_Current->dict = PyDict_New();
if (_PyThreadState_Current->dict == NULL) {
PyObject *d;
_PyThreadState_Current->dict = d = PyDict_New();
if (d == NULL)
PyErr_Clear();
}
return _PyThreadState_Current->dict;
}
......
......@@ -280,14 +280,6 @@ Py_Finalize(void)
/* Clear interpreter state */
PyInterpreterState_Clear(interp);
#ifdef Py_TRACE_REFS
/* Dump references -- this may implicitly need the thread state,
so this is the last possible place where we can do this. */
if (Py_GETENV("PYTHONDUMPREFS")) {
_Py_PrintReferences(stderr);
}
#endif /* Py_TRACE_REFS */
/* Delete current thread */
PyThreadState_Swap(NULL);
PyInterpreterState_Delete(interp);
......@@ -314,6 +306,14 @@ Py_Finalize(void)
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
#ifdef Py_TRACE_REFS
/* Dump references -- this may implicitly need the thread state,
so this is the last possible place where we can do this. */
if (Py_GETENV("PYTHONDUMPREFS")) {
_Py_PrintReferences(stderr);
}
#endif /* Py_TRACE_REFS */
#ifdef PYMALLOC_DEBUG
if (Py_GETENV("PYTHONMALLOCSTATS"))
_PyObject_DebugMallocStats();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment