From 28c15d913edf05cddcbe2cbf8c4fa6b5b9933c29 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 1 Jun 2018 09:11:31 -0600 Subject: [PATCH 1/3] Re-enable the crashing test. --- Lib/test/test__xxsubinterpreters.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py index 0667f14f7bf475..f66cc95169260d 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -1315,8 +1315,6 @@ def test_run_string_arg_unresolved(self): self.assertEqual(obj, b'spam') self.assertEqual(out.strip(), 'send') - # XXX Fix the crashes. - @unittest.skip('bpo-33615: triggering crashes so temporarily disabled') def test_run_string_arg_resolved(self): cid = interpreters.channel_create() cid = interpreters._channel_id(cid, _resolve=True) From 435ce8bdeb6be3082a522e6a725e2e4a2c2aaebb Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 30 May 2018 10:05:23 -0600 Subject: [PATCH 2/3] Move incref responsibility to getdata funcs. --- Include/internal/pystate.h | 7 ++++--- Modules/_xxsubinterpretersmodule.c | 1 + Python/pystate.c | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Include/internal/pystate.h b/Include/internal/pystate.h index da642c6fd00794..70e06666258279 100644 --- a/Include/internal/pystate.h +++ b/Include/internal/pystate.h @@ -80,7 +80,7 @@ struct _xid; // _PyCrossInterpreterData is similar to Py_buffer as an effectively // opaque struct that holds data outside the object machinery. This -// is necessary to pass between interpreters in the same process. +// is necessary to pass safely between interpreters in the same process. typedef struct _xid { // data is the cross-interpreter-safe derivation of a Python object // (see _PyObject_GetCrossInterpreterData). It will be NULL if the @@ -89,8 +89,9 @@ typedef struct _xid { // obj is the Python object from which the data was derived. This // is non-NULL only if the data remains bound to the object in some // way, such that the object must be "released" (via a decref) when - // the data is released. In that case it is automatically - // incref'ed (to match the automatic decref when releaed). + // the data is released. In that case the code that sets the field, + // likely a registered "crossinterpdatafunc", is responsible for + // ensuring it owns the reference (i.e. incref). PyObject *obj; // interp is the ID of the owning interpreter of the original // object. It corresponds to the active interpreter when diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index f3e65cd187ed76..129067cbd1924a 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1712,6 +1712,7 @@ _channelid_shared(PyObject *obj, _PyCrossInterpreterData *data) xid->resolve = ((channelid *)obj)->resolve; data->data = xid; + Py_INCREF(obj); data->obj = obj; data->new_object = _channelid_from_xid; data->free = PyMem_Free; diff --git a/Python/pystate.c b/Python/pystate.c index 4534c4770f24c5..08c5aa1ce8f46d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1205,7 +1205,6 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) } // Fill in the blanks and validate the result. - Py_XINCREF(data->obj); data->interp = interp->id; if (_check_xidata(data) != 0) { _PyCrossInterpreterData_Release(data); @@ -1355,6 +1354,7 @@ _bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) return -1; } data->data = (void *)shared; + Py_INCREF(obj); data->obj = obj; // Will be "released" (decref'ed) when data released. data->new_object = _new_bytes_object; data->free = PyMem_Free; @@ -1382,6 +1382,7 @@ _str_shared(PyObject *obj, _PyCrossInterpreterData *data) shared->buffer = PyUnicode_DATA(obj); shared->len = PyUnicode_GET_LENGTH(obj) - 1; data->data = (void *)shared; + Py_INCREF(obj); data->obj = obj; // Will be "released" (decref'ed) when data released. data->new_object = _new_str_object; data->free = PyMem_Free; From ea22ea33b995034889a867159d5ee1784e091714 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 30 May 2018 10:07:49 -0600 Subject: [PATCH 3/3] Factor out _call_in_interpreter(). --- Python/pystate.c | 52 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/Python/pystate.c b/Python/pystate.c index 08c5aa1ce8f46d..629598e215ef88 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1214,6 +1214,40 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) return 0; } +static void +_release_xidata(void *arg) +{ + _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; + if (data->free != NULL) { + data->free(data->data); + } + Py_XDECREF(data->obj); +} + +static void +_call_in_interpreter(PyInterpreterState *interp, + void (*func)(void *), void *arg) +{ + /* We would use Py_AddPendingCall() if it weren't specific to the + * main interpreter (see bpo-33608). In the meantime we take a + * naive approach. + */ + PyThreadState *save_tstate = NULL; + if (interp != PyThreadState_Get()->interp) { + // XXX Using the "head" thread isn't strictly correct. + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + // XXX Possible GILState issues? + save_tstate = PyThreadState_Swap(tstate); + } + + func(arg); + + // Switch back. + if (save_tstate != NULL) { + PyThreadState_Swap(save_tstate); + } +} + void _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) { @@ -1232,24 +1266,8 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) return; } - PyThreadState *save_tstate = NULL; - if (interp != PyThreadState_Get()->interp) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - // XXX Possible GILState issues? - save_tstate = PyThreadState_Swap(tstate); - } - // "Release" the data and/or the object. - if (data->free != NULL) { - data->free(data->data); - } - Py_XDECREF(data->obj); - - // Switch back. - if (save_tstate != NULL) { - PyThreadState_Swap(save_tstate); - } + _call_in_interpreter(interp, _release_xidata, data); } PyObject * pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy