Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TMemoryRegulator.cxx
Go to the documentation of this file.
1
2// Author: Enric Tejedor CERN 08/2019
3
4/*************************************************************************
5 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TMemoryRegulator.h"
13
14#include "../../cppyy/CPyCppyy/src/ProxyWrappers.h"
15#include "../../cppyy/CPyCppyy/src/CPPInstance.h"
16
17using namespace CPyCppyy;
18
20
21////////////////////////////////////////////////////////////////////////////
22/// \brief Constructor. Registers the hooks to run on Cppyy's object
23/// construction and destruction
25{
28}
29
30////////////////////////////////////////////////////////////////////////////
31/// \brief Register a hook that Cppyy runs when constructing an object.
32/// \param[in] cppobj Address of the object.
33/// \param[in] klass Class id of the object.
34/// \return Pair of two booleans. First indicates success, second tells
35/// Cppyy if we want to continue running RegisterPyObject
37{
38 static Cppyy::TCppType_t tobjectTypeID = (Cppyy::TCppType_t)Cppyy::GetScope("TObject");
39
40 if (Cppyy::IsSubtype(klass, tobjectTypeID)) {
41 ObjectMap_t::iterator ppo = fObjectMap.find(cppobj);
42 if (ppo == fObjectMap.end()) {
43 fObjectMap.insert({cppobj, klass});
44 }
45 }
46
47 return {true, true};
48}
49
50////////////////////////////////////////////////////////////////////////////
51/// \brief Register a hook that Cppyy runs when deleting an object.
52/// \param[in] cppobj Address of the object.
53/// \param[in] klass Class id of the object.
54/// \return Pair of two booleans. First indicates success, second tells
55/// Cppyy if we want to continue running UnRegisterPyObject
57{
58 static Cppyy::TCppType_t tobjectTypeID = (Cppyy::TCppType_t)Cppyy::GetScope("TObject");
59
60 if (Cppyy::IsSubtype(klass, tobjectTypeID)) {
61 ObjectMap_t::iterator ppo = fObjectMap.find(cppobj);
62 if (ppo != fObjectMap.end()) {
63 fObjectMap.erase(ppo);
64 }
65 }
66
67 return {true, true};
68}
69
70////////////////////////////////////////////////////////////////////////////
71/// \brief Get the class id of the TObject being deleted and run Cppyy's
72/// RecursiveRemove.
73/// \param[in] object Object being destructed.
75{
76 auto cppobj = (Cppyy::TCppObject_t)object;
77 Cppyy::TCppType_t klass = 0;
78
79 ObjectMap_t::iterator ppo = fObjectMap.find(cppobj);
80 if (ppo != fObjectMap.end()) {
81 klass = ppo->second;
83 fObjectMap.erase(ppo);
84 }
85}
86
87////////////////////////////////////////////////////////////////////////////
88/// \brief Clean up all tracked objects.
90{
91 while (!fObjectMap.empty()) {
92 auto elem = fObjectMap.begin();
93 auto cppobj = elem->first;
94 auto klassid = elem->second;
95 auto pyclass = CreateScopeProxy(klassid);
96 auto pyobj = (CPPInstance *)MemoryRegulator::RetrievePyObject(cppobj, pyclass);
97
98 if (pyobj && (pyobj->fFlags & CPPInstance::kIsOwner)) {
99 // Only delete the C++ object if the Python proxy owns it.
100 // If it is a value, cppyy deletes it in RecursiveRemove as part of
101 // the proxy cleanup.
102 auto o = static_cast<TObject *>(cppobj);
103 bool isValue = pyobj->fFlags & CPPInstance::kIsValue;
104 RecursiveRemove(o);
105 if (!isValue)
106 delete o;
107 }
108 else {
109 // Non-owning proxy, just unregister to clean tables.
110 // The proxy deletion by Python will have no effect on C++, so all good
112 }
113 }
114}
static bool RecursiveRemove(Cppyy::TCppObject_t cppobj, Cppyy::TCppType_t klass)
static PyObject * RetrievePyObject(Cppyy::TCppObject_t cppobj, PyObject *pyclass)
static void SetUnregisterHook(MemHook_t h)
static void SetRegisterHook(MemHook_t h)
static bool UnregisterPyObject(CPPInstance *pyobj, PyObject *pyclass)
static std::pair< bool, bool > RegisterHook(Cppyy::TCppObject_t, Cppyy::TCppType_t)
Register a hook that Cppyy runs when constructing an object.
virtual void RecursiveRemove(TObject *)
Get the class id of the TObject being deleted and run Cppyy's RecursiveRemove.
static ObjectMap_t fObjectMap
void ClearProxiedObjects()
Clean up all tracked objects.
static std::pair< bool, bool > UnregisterHook(Cppyy::TCppObject_t, Cppyy::TCppType_t)
Register a hook that Cppyy runs when deleting an object.
Mother of all ROOT objects.
Definition TObject.h:41
PyObject * CreateScopeProxy(Cppyy::TCppScope_t, const unsigned flags=0)
RPY_EXPORTED bool IsSubtype(TCppType_t derived, TCppType_t base)
void * TCppObject_t
Definition cpp_cppyy.h:21
TCppScope_t TCppType_t
Definition cpp_cppyy.h:19
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
std::unordered_map< Cppyy::TCppObject_t, Cppyy::TCppType_t > ObjectMap_t