itom
Loading...
Searching...
No Matches
pythonSharedPointerGuard.h
1/* ********************************************************************
2 itom software
3 URL: http://www.uni-stuttgart.de/ito
4 Copyright (C) 2020, Institut für Technische Optik (ITO),
5 Universität Stuttgart, Germany
6
7 This file is part of itom.
8
9 itom is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Library General Public Licence as published by
11 the Free Software Foundation; either version 2 of the Licence, or (at
12 your option) any later version.
13
14 itom is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
17 General Public Licence for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with itom. If not, see <http://www.gnu.org/licenses/>.
21*********************************************************************** */
22
23#pragma once
24
25//python
26#ifndef Q_MOC_RUN
27#include "python/pythonWrapper.h"
28#endif
29
30#include "../../common/sharedStructures.h"
31#include "../global.h"
32
33#include <qhash.h>
34#include <qsharedpointer.h>
35
36namespace ito
37{
38
40/*
41If a PyObject wraps an object, like a dataObject, pointCloud etc,
42which should accessed via a QSharedPointer, this class can be
43used to safely get the sharedPointer. As long as the shared pointer exists,
44the refcount of the original PyObject is incremented to make sure,
45that the internal object is not destroyed. If the shared pointer is
46destroyed, the PythonSharedPointerGuard::deleter is called and decrements
47the refcount of the guarded PyObject.
48*/
50{
51private:
56 static void safeDecrefPyObject2Async(PyObject* obj);
57
59 template<typename _Tp> static void deleter(_Tp *sharedPointerData)
60 {
61 auto iter = m_hashTable.find((void*)sharedPointerData);
62
63 if (iter != m_hashTable.end())
64 {
65 PyObject *val = iter.value();
66
67 if (val)
68 {
69 if (PyGILState_Check())
70 {
71 Py_DECREF(val);
72 }
73 else
74 {
76 }
77 }
78
79 m_hashTable.erase(iter);
80 }
81 }
82
83public:
85 /*
86 \param sharedPointerData is the object, owned by pyObjOwner, that
87 should be returned within the QSharedPointer.
88 \param pyObjOwner is the PyObject, that is the owner of the
89 sharedPointerData. Its ref count is incremented by one as long
90 as the returned shared pointer exists.
91 */
92 template<typename _Tp> static QSharedPointer<_Tp> createPythonSharedPointer(_Tp *sharedPointerData, PyObject *pyObjOwner)
93 {
94 Py_XINCREF(pyObjOwner);
95 m_hashTable.insert((void*)sharedPointerData, pyObjOwner);
96 return QSharedPointer<_Tp>(sharedPointerData, deleter<_Tp>);
97 }
98
99private:
100
101 /* elements in this hash-table are pyObjects (type byteArray, unicode...),
102 whose inlying char*-pointer is given to a QSharedPointer<char>. Before giving
103 it to the shared pointer, the reference of the pyObject is incremented.
104 If the deleter of the sharedPointer is called, it does not delete the char-array,
105 but decrements the PyObject and deletes it from this hash-table (used in getVal) */
106 static QHash<void* /*sharedPointerData*/, PyObject* /*pyObjOwner*/> m_hashTable;
107
108};
109
110} //namespace ito
Guard for a shared pointer of a PyObject.
Definition pythonSharedPointerGuard.h:50
static QSharedPointer< _Tp > createPythonSharedPointer(_Tp *sharedPointerData, PyObject *pyObjOwner)
< main method to get the guarded shared pointer
Definition pythonSharedPointerGuard.h:92
static void safeDecrefPyObject2Async(PyObject *obj)
user-defined deleter for the QSharedPointer, released by createPythonSharedPointer
Definition pythonSharedPointerGuard.cpp:49
Definition apiFunctionsGraph.cpp:40