ATLAS Offline Software
Loading...
Searching...
No Matches
T_AthenaPoolCustCnv.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5/** @file T_AthenaPoolCustCnv.icc
6 * @brief This file contains the implementation for the templated T_AthenaPoolCustCnv class.
7 * @author Peter van Gemmeren <gemmeren@anl.gov>
8 **/
9
10#include "AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h"
11#include "AthenaPoolCnvSvc/exceptions.h"
12
13#include "GaudiKernel/StatusCode.h"
14#include "GaudiKernel/DataObject.h"
15#include "GaudiKernel/IOpaqueAddress.h"
16#include "GaudiKernel/IRegistry.h"
17
18#include "AthenaKernel/CLASS_DEF.h"
19#include "AthenaKernel/ClassName.h"
20#include "AthenaKernel/StorableConversions.h"
21#include "PersistentDataModel/Token.h"
22
23//__________________________________________________________________________
24template <class TRANS, class PERS>
25T_AthenaPoolCustCnv<TRANS, PERS>::T_AthenaPoolCustCnv(ISvcLocator* pSvcLocator,
26 const char* name /*= nullptr*/)
27 : T_AthenaPoolCnvBase<TRANS>(pSvcLocator, name), m_className(), m_classDescs() {
28}
29//______________________________________________________________________________
30template <class TRANS, class PERS>
31StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::initialize() {
32 ATH_MSG_DEBUG("initialize() in T_AthenaPoolCustCnv " << classID());
33 if (!T_AthenaPoolCnvBase<TRANS>::initialize().isSuccess()) {
34 ATH_MSG_FATAL("Failed to initialize AthenaPoolConverter base class.");
35 return(StatusCode::FAILURE);
36 }
37 return(this->m_athenaPoolCnvSvc->registerCleanUp(this));
38}
39//__________________________________________________________________________
40template <class TRANS, class PERS>
41CLID T_AthenaPoolCustCnv<TRANS, PERS>::classID() {
42 return(ClassID_traits<TRANS>::ID());
43}
44//__________________________________________________________________________
45template <class TRANS, class PERS>
46template <class P>
47Placement T_AthenaPoolCustCnv<TRANS, PERS>::setPlacementForP(P& /*p*/, const std::string& key, const std::string& output) {
48 const std::string typenm = ClassName<P>::name();
49 return(this->setPlacementWithType(typenm, key, output));
50}
51//__________________________________________________________________________
52template <class TRANS, class PERS>
53template <class P>
54StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, std::unique_ptr<Token>& token, const std::string& key, const std::string& output) {
55 const static std::string className = ClassName<P>::name();
56 // Check dictionary
57 std::lock_guard<AthenaPoolConverter::CallMutex> lock(this->m_conv_mut);
58 // Allow for multiple class names
59 if (m_className != className) {
60 m_className = className;
61 // Different class name - get description
62 auto itClass = m_classDescs.find(className);
63 if (itClass == m_classDescs.end()) {
64 // For new class names, check dictionary
65 m_classDescs[className] = RootType( typeid(P) );
66 }
67 }
68 Placement placement = setPlacementForP(*pObj, key, output);
69 token.reset(this->m_athenaPoolCnvSvc->registerForWrite(&placement, pObj, m_classDescs[m_className]));
70 return(StatusCode::SUCCESS);
71}
72//__________________________________________________________________________
73template <class TRANS, class PERS>
74template <class P>
75StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::poolToObject(const Token* token, P*& pObj) {
76 pObj = nullptr;
77 void* voidPtr = nullptr;
78 try {
79 this->m_athenaPoolCnvSvc->setObjPtr(voidPtr, token);
80 }
81 catch (const std::exception& ex) {
82 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
83 "pooltoObject",
84 ex,
85 typeid(P),
86 token != nullptr ? token->toString() : "");
87 }
88 if (voidPtr == nullptr) {
89 ATH_MSG_ERROR("poolToObject: Could not get object for Token = " << (token != nullptr ? token->toString() : ""));
90 return(StatusCode::FAILURE);
91 }
92 pObj = reinterpret_cast<P*>(voidPtr);
93 return(StatusCode::SUCCESS);
94}
95//__________________________________________________________________________
96template <class TRANS, class PERS>
97StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::DataObjectToPool(IOpaqueAddress* pAddr, DataObject* pObj) {
98 const std::string className = ClassName<TRANS>::name();
99 ATH_MSG_DEBUG("Called DataObjectToPool for " << pObj << ": " << className << ", with key " << pObj->name());
100 PERS* persObj = nullptr;
101 TRANS* obj = nullptr;
102 bool success = SG::fromStorable(pObj, obj);
103 if (!success || obj == nullptr) {
104 ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << pObj->name());
105 return(StatusCode::FAILURE);
106 }
107 {
108 std::lock_guard<AthenaPoolConverter::CallMutex> lock(this->m_conv_mut);
109 if (!transToPers(obj, persObj).isSuccess()) {
110 ATH_MSG_ERROR("Failed to convert to persistent DataType for class (type/key) " << className << "/" << pObj->name());
111 return(StatusCode::FAILURE);
112 }
113 }
114 std::unique_ptr<Token> token;
115 StatusCode status = objectToPool<PERS>(persObj, token, pObj->name(), *pAddr->par());
116 // Null/empty token means ERROR
117 if (token == nullptr || token->classID() == Guid::null()) {
118 ATH_MSG_ERROR("Failed to get Token for class (type/key) " << className << "/" << pObj->name());
119 return(StatusCode::FAILURE);
120 }
121 // Update IOpaqueAddress for this object.
122 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
123 if (tokAddr != nullptr) {
124 tokAddr->setToken(std::move(token));
125 } else {
126 return(StatusCode::FAILURE);
127 }
128 return(status);
129}
130//__________________________________________________________________________
131template <class TRANS, class PERS>
132StatusCode
133T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
134 const Token* token,
135 const std::string& /*key*/)
136{
137 TRANS* transObj = nullptr;
138 PERS* obj = nullptr;
139 if (!poolToObject<PERS>(token, obj).isSuccess()) {
140 ATH_MSG_ERROR("Failed to read persistent DataType");
141 return(StatusCode::FAILURE);
142 }
143 {
144 std::lock_guard<AthenaPoolConverter::CallMutex> lock(this->m_conv_mut);
145 if (!persToTrans(transObj, obj).isSuccess()) {
146 delete transObj; transObj = nullptr;
147 delete obj; obj = nullptr;
148 ATH_MSG_ERROR("Failed to convert to transient DataType");
149 return(StatusCode::FAILURE);
150 }
151 }
152 delete obj; obj = nullptr;
153 pObj = SG::asStorable(transObj);
154 return(StatusCode::SUCCESS);
155}
156//__________________________________________________________________________
157// Compare POOL class GUID with the one from object being read
158// To be used in createTransient(const Token* token)
159template <class TRANS, class PERS>
160inline bool T_AthenaPoolCustCnv<TRANS, PERS>::compareClassGuid(const Token* token, const Guid &guid) const {
161 return(token ? (guid == token->classID()) : false);
162}