Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
67a88c2
Factor out _Py_excinfo.
ericsnowcurrently Oct 24, 2023
a9ea9ac
Extract _PyXI_errcode.
ericsnowcurrently Oct 25, 2023
33d91af
Extract _PyXI_exception_info.
ericsnowcurrently Oct 25, 2023
2424e33
Extract _PyXI_namespace.
ericsnowcurrently Oct 25, 2023
23d6959
Factor out _enter_interpreter(), _exit_interpreter(), etc.
ericsnowcurrently Oct 23, 2023
b08249f
Move enter/exit to crossinterp.c.
ericsnowcurrently Oct 27, 2023
773f5ab
Factor out _sharednsitem_set_value().
ericsnowcurrently Oct 23, 2023
cf7354e
Add _PyXI_NamespaceFromNames().
ericsnowcurrently Oct 31, 2023
6b43620
Add a default arg to _PyXI_ApplyNamespace().
ericsnowcurrently Oct 31, 2023
caef717
Allocate xid dynamically when in target interpreter.
ericsnowcurrently Oct 31, 2023
0bd42e0
Add _PyXI_FillNamespaceFromDict().
ericsnowcurrently Oct 31, 2023
a230f77
Add xid_state structs and lifecycle funcs.
ericsnowcurrently Oct 31, 2023
5675f86
Add PyExc_NotShareableError.
ericsnowcurrently Oct 31, 2023
45488f2
Propagate the ValueError when a value is not shareable.
ericsnowcurrently Oct 31, 2023
6f07364
Propagate errors in _PyXI_Enter() directly.
ericsnowcurrently Oct 31, 2023
0201b7f
Factor out _init_not_shareable_error_type() and _fini_not_shareable_e…
ericsnowcurrently Nov 1, 2023
d32a918
Drop some duplicate lines.
ericsnowcurrently Nov 1, 2023
1d4fc87
Fix a comment.
ericsnowcurrently Nov 1, 2023
88c9d54
Call _PyXI_Fini() *before* the interpreter is cleared.
ericsnowcurrently Nov 1, 2023
2edcb49
Fix init/fini.
ericsnowcurrently Nov 1, 2023
8e53752
Add _get_not_shareable_error_type().
ericsnowcurrently Nov 1, 2023
53764c1
Export fewer symbols.
ericsnowcurrently Nov 1, 2023
cacf969
Merge branch 'main' into crossinterp-utils-additions
ericsnowcurrently Nov 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Extract _PyXI_namespace.
  • Loading branch information
ericsnowcurrently committed Oct 30, 2023
commit 2424e33c71038cc1712dfff5bf2b8d860d6c96b7
7 changes: 7 additions & 0 deletions Include/internal/pycore_crossinterp.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ PyAPI_FUNC(void) _PyXI_ApplyExceptionInfo(
PyObject *exctype);


typedef struct _sharedns _PyXI_namespace;

PyAPI_FUNC(void) _PyXI_FreeNamespace(_PyXI_namespace *ns);
PyAPI_FUNC(_PyXI_namespace *) _PyXI_NamespaceFromDict(PyObject *nsobj);
PyAPI_FUNC(int) _PyXI_ApplyNamespace(_PyXI_namespace *ns, PyObject *nsobj);


#ifdef __cplusplus
}
#endif
Expand Down
167 changes: 4 additions & 163 deletions Modules/_xxsubinterpretersmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,6 @@
#define MODULE_NAME "_xxsubinterpreters"


static const char *
_copy_raw_string(PyObject *strobj)
{
const char *str = PyUnicode_AsUTF8(strobj);
if (str == NULL) {
return NULL;
}
char *copied = PyMem_RawMalloc(strlen(str)+1);
if (copied == NULL) {
PyErr_NoMemory();
return NULL;
}
strcpy(copied, str);
return copied;
}

static PyInterpreterState *
_get_current_interp(void)
{
Expand Down Expand Up @@ -63,21 +47,6 @@ add_new_exception(PyObject *mod, const char *name, PyObject *base)
#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \
add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE)

static int
_release_xid_data(_PyCrossInterpreterData *data)
{
PyObject *exc = PyErr_GetRaisedException();
int res = _PyCrossInterpreterData_Release(data);
if (res < 0) {
/* The owning interpreter is already destroyed. */
_PyCrossInterpreterData_Clear(NULL, data);
// XXX Emit a warning?
PyErr_Clear();
}
PyErr_SetRaisedException(exc);
return res;
}


/* module state *************************************************************/

Expand Down Expand Up @@ -114,134 +83,6 @@ clear_module_state(module_state *state)
}


/* data-sharing-specific code ***********************************************/

struct _sharednsitem {
const char *name;
_PyCrossInterpreterData data;
};

static void _sharednsitem_clear(struct _sharednsitem *); // forward

static int
_sharednsitem_init(struct _sharednsitem *item, PyObject *key, PyObject *value)
{
item->name = _copy_raw_string(key);
if (item->name == NULL) {
return -1;
}
if (_PyObject_GetCrossInterpreterData(value, &item->data) != 0) {
_sharednsitem_clear(item);
return -1;
}
return 0;
}

static void
_sharednsitem_clear(struct _sharednsitem *item)
{
if (item->name != NULL) {
PyMem_RawFree((void *)item->name);
item->name = NULL;
}
(void)_release_xid_data(&item->data);
}

static int
_sharednsitem_apply(struct _sharednsitem *item, PyObject *ns)
{
PyObject *name = PyUnicode_FromString(item->name);
if (name == NULL) {
return -1;
}
PyObject *value = _PyCrossInterpreterData_NewObject(&item->data);
if (value == NULL) {
Py_DECREF(name);
return -1;
}
int res = PyDict_SetItem(ns, name, value);
Py_DECREF(name);
Py_DECREF(value);
return res;
}

typedef struct _sharedns {
Py_ssize_t len;
struct _sharednsitem* items;
} _sharedns;

static _sharedns *
_sharedns_new(Py_ssize_t len)
{
_sharedns *shared = PyMem_RawCalloc(sizeof(_sharedns), 1);
if (shared == NULL) {
PyErr_NoMemory();
return NULL;
}
shared->len = len;
shared->items = PyMem_RawCalloc(sizeof(struct _sharednsitem), len);
if (shared->items == NULL) {
PyErr_NoMemory();
PyMem_RawFree(shared);
return NULL;
}
return shared;
}

static void
_sharedns_free(_sharedns *shared)
{
for (Py_ssize_t i=0; i < shared->len; i++) {
_sharednsitem_clear(&shared->items[i]);
}
PyMem_RawFree(shared->items);
PyMem_RawFree(shared);
}

static _sharedns *
_get_shared_ns(PyObject *shareable)
{
if (shareable == NULL || shareable == Py_None) {
return NULL;
}
Py_ssize_t len = PyDict_Size(shareable);
if (len == 0) {
return NULL;
}

_sharedns *shared = _sharedns_new(len);
if (shared == NULL) {
return NULL;
}
Py_ssize_t pos = 0;
for (Py_ssize_t i=0; i < len; i++) {
PyObject *key, *value;
if (PyDict_Next(shareable, &pos, &key, &value) == 0) {
break;
}
if (_sharednsitem_init(&shared->items[i], key, value) != 0) {
break;
}
}
if (PyErr_Occurred()) {
_sharedns_free(shared);
return NULL;
}
return shared;
}

static int
_sharedns_apply(_sharedns *shared, PyObject *ns)
{
for (Py_ssize_t i=0; i < shared->len; i++) {
if (_sharednsitem_apply(&shared->items[i], ns) != 0) {
return -1;
}
}
return 0;
}


/* Python code **************************************************************/

static const char *
Expand Down Expand Up @@ -363,7 +204,7 @@ exceptions_init(PyObject *mod)
static int
_run_script(PyInterpreterState *interp,
const char *codestr, Py_ssize_t codestrlen,
_sharedns *shared, _PyXI_exception_info *sharedexc, int flags)
_PyXI_namespace *shared, _PyXI_exception_info *sharedexc, int flags)
{
PyObject *excval = NULL;
_PyXI_errcode errcode = _PyXI_ERR_UNCAUGHT_EXCEPTION;
Expand Down Expand Up @@ -391,7 +232,7 @@ _run_script(PyInterpreterState *interp,

// Apply the cross-interpreter data.
if (shared != NULL) {
if (_sharedns_apply(shared, ns) != 0) {
if (_PyXI_ApplyNamespace(shared, ns) != 0) {
Py_DECREF(ns);
goto error;
}
Expand Down Expand Up @@ -462,7 +303,7 @@ _run_in_interpreter(PyObject *mod, PyInterpreterState *interp,
module_state *state = get_module_state(mod);
assert(state != NULL);

_sharedns *shared = _get_shared_ns(shareables);
_PyXI_namespace *shared = _PyXI_NamespaceFromDict(shareables);
if (shared == NULL && PyErr_Occurred()) {
return -1;
}
Expand Down Expand Up @@ -496,7 +337,7 @@ _run_in_interpreter(PyObject *mod, PyInterpreterState *interp,
}

if (shared != NULL) {
_sharedns_free(shared);
_PyXI_FreeNamespace(shared);
}

return result;
Expand Down
Loading