diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2025-09-26 09:45:16 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2025-10-02 17:42:48 +0200 |
| commit | c630f1c87a77ccd7fb80782d48743e70dec56ae0 (patch) | |
| tree | 7cc6954d0431a1c306b1c33a55d286cc391796e6 /sources/pyside6 | |
| parent | 83cbfe0bc6ee4b7f8441bff10d76982966e78628 (diff) | |
libpyside: Add globals structure
Put global data into a struct which in the future will exist
per interpreter as interpreters can only share immortal objects.
Task-number: PYSIDE-3155
Change-Id: I45ccaac57b41219bd4bd6a9151f820b00a787b0e
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/pyside6')
| -rw-r--r-- | sources/pyside6/libpyside/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | sources/pyside6/libpyside/feature_select.cpp | 39 | ||||
| -rw-r--r-- | sources/pyside6/libpyside/pyside.cpp | 7 | ||||
| -rw-r--r-- | sources/pyside6/libpyside/pysideglobals.cpp | 15 | ||||
| -rw-r--r-- | sources/pyside6/libpyside/pysideglobals_p.h | 29 | ||||
| -rw-r--r-- | sources/pyside6/libpyside/pysideslot.cpp | 3 | ||||
| -rw-r--r-- | sources/pyside6/libpyside/signalmanager.cpp | 5 |
7 files changed, 77 insertions, 23 deletions
diff --git a/sources/pyside6/libpyside/CMakeLists.txt b/sources/pyside6/libpyside/CMakeLists.txt index 75c232874..2adc9c905 100644 --- a/sources/pyside6/libpyside/CMakeLists.txt +++ b/sources/pyside6/libpyside/CMakeLists.txt @@ -27,6 +27,7 @@ set(libpyside_HEADERS # installed below pysidemetatype.h pyside_numpy.h pyside_p.h + pysideglobals_p.h pysideproperty.h pysideproperty_p.h pysideqapp.h @@ -54,6 +55,7 @@ set(libpyside_SRC signalmanager.cpp pysideclassdecorator.cpp pysideclassinfo.cpp + pysideglobals.cpp pysideqenum.cpp pysideqslotobject_p.cpp pysidemetafunction.cpp diff --git a/sources/pyside6/libpyside/feature_select.cpp b/sources/pyside6/libpyside/feature_select.cpp index 60659b2d6..7ffee717d 100644 --- a/sources/pyside6/libpyside/feature_select.cpp +++ b/sources/pyside6/libpyside/feature_select.cpp @@ -5,6 +5,7 @@ #include "basewrapper.h" #include "pysidestaticstrings.h" #include "class_property.h" +#include "pysideglobals_p.h" #include <autodecref.h> #include <sbkfeature_base.h> @@ -119,15 +120,17 @@ createDerivedDictType() return reinterpret_cast<PyTypeObject *>(ChameleonDict); } -static PyTypeObject *new_dict_type = nullptr; - -static void ensureNewDictType() +static PyTypeObject *ensureNewDictType() { - if (new_dict_type == nullptr) { - new_dict_type = createDerivedDictType(); - if (new_dict_type == nullptr) + auto *globals = PySide::globals(); + if (globals->newFeatureDictType == nullptr) { + globals->newFeatureDictType = createDerivedDictType(); + if (globals->newFeatureDictType == nullptr) { + PyErr_Print(); Py_FatalError("libshiboken: Problem creating ChameleonDict"); + } } + return globals->newFeatureDictType; } static inline PyObject *nextInCircle(PyObject *dict) @@ -165,9 +168,8 @@ static bool replaceClassDict(PyTypeObject *type) * Replace the type dict by the derived ChameleonDict. * This is mandatory for all type dicts when they are touched. */ - ensureNewDictType(); + auto *ob_ndt = reinterpret_cast<PyObject *>(ensureNewDictType()); AutoDecRef dict(PepType_GetDict(type)); - auto *ob_ndt = reinterpret_cast<PyObject *>(new_dict_type); auto *new_dict = PyObject_CallObject(ob_ndt, nullptr); if (new_dict == nullptr || PyDict_Update(new_dict, dict) < 0) return false; @@ -190,7 +192,7 @@ static bool addNewDict(PyTypeObject *type, int select_id) */ AutoDecRef dict(PepType_GetDict(type)); AutoDecRef orig_dict(PyObject_GetAttr(dict, PySideName::orig_dict())); - auto *ob_ndt = reinterpret_cast<PyObject *>(new_dict_type); + auto *ob_ndt = reinterpret_cast<PyObject *>(ensureNewDictType()); auto *new_dict = PyObject_CallObject(ob_ndt, nullptr); if (new_dict == nullptr) return false; @@ -293,13 +295,16 @@ static inline void SelectFeatureSetSubtype(PyTypeObject *type, int select_id) } } -static PyObject *cached_globals{}; -static int last_select_id{}; - static inline int getFeatureSelectId() { static auto *undef = PyLong_FromLong(-1); - static auto *feature_dict = GetFeatureDict(); + + auto *libGlobals = PySide::globals(); + PyObject *&feature_dict = PySide::globals()->featureDict; + if (feature_dict == nullptr) + feature_dict = GetFeatureDict(); + PyObject *&cached_globals = libGlobals->cachedFeatureGlobals; + int &last_select_id = libGlobals->lastSelectedFeatureId; Shiboken::AutoDecRef globals(PepEval_GetFrameGlobals()); if (globals.isNull() || globals.object() == cached_globals) @@ -342,7 +347,7 @@ static inline void SelectFeatureSet(PyTypeObject *type) int select_id = getFeatureSelectId(); static int last_select_id{}; - static PyTypeObject *last_type{}; + PyTypeObject *&last_type = PySide::globals()->lastFeatureType; // PYSIDE-2029: Implement a very simple but effective cache that cannot fail. if (type == last_type && select_id == last_select_id) @@ -415,9 +420,11 @@ void init() patch_property_impl(); is_initialized = true; } - last_select_id = 0; + // Reset the cache. This is called at any "from __feature__ import". - cached_globals = nullptr; + auto *globals = PySide::globals(); + globals->lastSelectedFeatureId = 0; + globals->cachedFeatureGlobals = nullptr; } void Enable(bool enable) diff --git a/sources/pyside6/libpyside/pyside.cpp b/sources/pyside6/libpyside/pyside.cpp index ca467c6c1..9901aefae 100644 --- a/sources/pyside6/libpyside/pyside.cpp +++ b/sources/pyside6/libpyside/pyside.cpp @@ -11,6 +11,7 @@ #include "pyside_p.h" #include "signalmanager.h" #include "pysideclassinfo_p.h" +#include "pysideglobals_p.h" #include "pysideproperty_p.h" #include "class_property.h" #include "pysideproperty.h" @@ -1020,18 +1021,16 @@ bool registerInternalQtConf() return isRegistered; } -static PyTypeObject *qObjType = nullptr; - PyTypeObject *qObjectType() { - PyTypeObject *result = qObjType; + PyTypeObject *result = globals()->qobjectType; Q_ASSERT(result); return result; } void setQObjectType(PyTypeObject *t) { - qObjType = t; + globals()->qobjectType = t; } bool isQObjectDerived(PyTypeObject *pyType, bool raiseError) diff --git a/sources/pyside6/libpyside/pysideglobals.cpp b/sources/pyside6/libpyside/pysideglobals.cpp new file mode 100644 index 000000000..86f1cb0ab --- /dev/null +++ b/sources/pyside6/libpyside/pysideglobals.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "pysideglobals_p.h" + +namespace PySide +{ + +Globals *globals() +{ + static Globals result; + return &result; +} + +} // namespace PySide diff --git a/sources/pyside6/libpyside/pysideglobals_p.h b/sources/pyside6/libpyside/pysideglobals_p.h new file mode 100644 index 000000000..be49cb221 --- /dev/null +++ b/sources/pyside6/libpyside/pysideglobals_p.h @@ -0,0 +1,29 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef PYSIDE_GLOBALS_P_H +#define PYSIDE_GLOBALS_P_H + +#include <sbkpython.h> + +namespace PySide +{ + +struct Globals // Per interpreter globals of libpyside +{ + PyTypeObject *newFeatureDictType = nullptr; + PyObject *featureDict = nullptr; + PyObject *cachedFeatureGlobals = nullptr; + PyTypeObject *lastFeatureType = nullptr; + int lastSelectedFeatureId = 0; + PyTypeObject *qobjectType = nullptr; + PyObject *emptyTuple = nullptr; + PyObject *pickleReduceFunc; + PyObject *pickleEvalFunc; +}; + +Globals *globals(); + +} //namespace PySide + +#endif //PYSIDE_GLOBALS_P_H diff --git a/sources/pyside6/libpyside/pysideslot.cpp b/sources/pyside6/libpyside/pysideslot.cpp index b426bec1a..9725b130d 100644 --- a/sources/pyside6/libpyside/pysideslot.cpp +++ b/sources/pyside6/libpyside/pysideslot.cpp @@ -4,6 +4,7 @@ #include "pysidesignal_p.h" #include "pysideslot_p.h" #include "pysidestaticstrings.h" +#include "pysideglobals_p.h" #include <autodecref.h> #include <basewrapper.h> @@ -74,12 +75,12 @@ static PyTypeObject *PySideSlot_TypeF() int slotTpInit(PyObject *self, PyObject *args, PyObject *kw) { - static PyObject *emptyTuple = nullptr; static const char *kwlist[] = {"name", "result", "tag", nullptr}; char *argName = nullptr; PyObject *argResult = nullptr; char *tag = nullptr; + PyObject *& emptyTuple = PySide::globals()->emptyTuple; if (emptyTuple == nullptr) emptyTuple = PyTuple_New(0); diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp index 9c00b4deb..211588eea 100644 --- a/sources/pyside6/libpyside/signalmanager.cpp +++ b/sources/pyside6/libpyside/signalmanager.cpp @@ -7,6 +7,7 @@ #include "pysideproperty.h" #include "pysideproperty_p.h" #include "pyside_p.h" +#include "pysideglobals_p.h" #include "dynamicqmetaobject.h" #include "pysidemetafunction_p.h" @@ -196,7 +197,7 @@ QDataStream &operator<<(QDataStream &out, const PyObjectWrapper &myObj) return out; } - static PyObject *reduce_func = nullptr; + PyObject *&reduce_func = PySide::globals()->pickleReduceFunc; Shiboken::GilState gil; if (!reduce_func) { @@ -228,7 +229,7 @@ QDataStream &operator>>(QDataStream &in, PyObjectWrapper &myObj) return in; } - static PyObject *eval_func = nullptr; + PyObject *&eval_func = PySide::globals()->pickleEvalFunc; Shiboken::GilState gil; if (!eval_func) { |
