summaryrefslogtreecommitdiffstats
path: root/Python/pystate.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c95
1 files changed, 47 insertions, 48 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index b872dc0..eca26c7 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -387,6 +387,53 @@ PyThreadState_Next(PyThreadState *tstate) {
return tstate->next;
}
+/* The implementation of sys._current_frames(). This is intended to be
+ called with the GIL held, as it will be when called via
+ sys._current_frames(). It's possible it would work fine even without
+ the GIL held, but haven't thought enough about that.
+*/
+PyObject *
+_PyThread_CurrentFrames(void)
+{
+ PyObject *result;
+ PyInterpreterState *i;
+
+ result = PyDict_New();
+ if (result == NULL)
+ return NULL;
+
+ /* for i in all interpreters:
+ * for t in all of i's thread states:
+ * if t's frame isn't NULL, map t's id to its frame
+ * Because these lists can mutute even when the GIL is held, we
+ * need to grab head_mutex for the duration.
+ */
+ HEAD_LOCK();
+ for (i = interp_head; i != NULL; i = i->next) {
+ PyThreadState *t;
+ for (t = i->tstate_head; t != NULL; t = t->next) {
+ PyObject *id;
+ int stat;
+ struct _frame *frame = t->frame;
+ if (frame == NULL)
+ continue;
+ id = PyInt_FromLong(t->thread_id);
+ if (id == NULL)
+ goto Fail;
+ stat = PyDict_SetItem(result, id, (PyObject *)frame);
+ Py_DECREF(id);
+ if (stat < 0)
+ goto Fail;
+ }
+ }
+ HEAD_UNLOCK();
+ return result;
+
+ Fail:
+ HEAD_UNLOCK();
+ Py_DECREF(result);
+ return NULL;
+}
/* Python "auto thread state" API. */
#ifdef WITH_THREAD
@@ -550,54 +597,6 @@ PyGILState_Release(PyGILState_STATE oldstate)
PyEval_SaveThread();
}
-/* The implementation of sys._current_frames(). This is intended to be
- called with the GIL held, as it will be when called via
- sys._current_frames(). It's possible it would work fine even without
- the GIL held, but haven't thought enough about that.
-*/
-PyObject *
-_PyThread_CurrentFrames(void)
-{
- PyObject *result;
- PyInterpreterState *i;
-
- result = PyDict_New();
- if (result == NULL)
- return NULL;
-
- /* for i in all interpreters:
- * for t in all of i's thread states:
- * if t's frame isn't NULL, map t's id to its frame
- * Because these lists can mutute even when the GIL is held, we
- * need to grab head_mutex for the duration.
- */
- HEAD_LOCK();
- for (i = interp_head; i != NULL; i = i->next) {
- PyThreadState *t;
- for (t = i->tstate_head; t != NULL; t = t->next) {
- PyObject *id;
- int stat;
- struct _frame *frame = t->frame;
- if (frame == NULL)
- continue;
- id = PyInt_FromLong(t->thread_id);
- if (id == NULL)
- goto Fail;
- stat = PyDict_SetItem(result, id, (PyObject *)frame);
- Py_DECREF(id);
- if (stat < 0)
- goto Fail;
- }
- }
- HEAD_UNLOCK();
- return result;
-
- Fail:
- HEAD_UNLOCK();
- Py_DECREF(result);
- return NULL;
-}
-
#ifdef __cplusplus
}
#endif