ATLAS Offline Software
Loading...
Searching...
No Matches
T_AthenaPoolCustomCnv.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_AthenaPoolCustomCnv.icc
6 * @brief This file contains the implementation for the templated T_AthenaPoolCustomCnv class.
7 * @author Marcin.Nowak@cern.ch
8 **/
9
10#include "GaudiKernel/StatusCode.h"
11#include "GaudiKernel/DataObject.h"
12#include "GaudiKernel/IOpaqueAddress.h"
13
14#include "StorageSvc/DbReflex.h"
15
16#include "AthenaKernel/StorableConversions.h"
17
18#include "AthenaPoolCnvSvc/exceptions.h"
19#include "AthenaPoolCnvTPExtension.h"
20
21#include <stdexcept>
22
23template <class TRANS, class PERS>
24T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::T_AthenaPoolCustomCnvWithKey(ISvcLocator* pSvcLocator,
25 const char* name /*= nullptr*/) : BaseType(pSvcLocator, name) {
26}
27
28template <class TRANS, class PERS>
29StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::DataObjectToPool(IOpaqueAddress* pAddr, DataObject* pObj) {
30 ATH_MSG_VERBOSE("In DataObjectToPool() for key = " << pObj->name());
31 TRANS* obj = nullptr;
32 PERS* persObj = nullptr;
33 bool success = SG::fromStorable(pObj, obj);
34 if (!success || obj == nullptr) {
35 ATH_MSG_ERROR("Failed to cast DataObject to transient type");
36 return(StatusCode::FAILURE);
37 }
38 try {
39 std::lock_guard<AthenaPoolConverter::CallMutex> lock(this->m_conv_mut);
40 persObj = createPersistentWithKey(obj, pObj->name());
41 }
42 catch (const std::exception& ex) {
43 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
44 "creating persistent object",
45 ex,
46 typeid(TRANS),
47 pObj->name());
48 }
49 std::unique_ptr<Token> token;
50 StatusCode status = this->objectToPool(persObj, token, pObj->name(), *pAddr->par());
51 // Null/empty token means ERROR
52 if (token == nullptr || token->classID() == Guid::null()) {
53 ATH_MSG_ERROR("failed to get Token for " << pObj->name());
54 return(StatusCode::FAILURE);
55 }
56 std::size_t cpos = pAddr->par()->find(':');
57 std::size_t bpos = pAddr->par()->find('[');
58 if (cpos == std::string::npos) {
59 cpos = 0;
60 } else {
61 cpos++;
62 }
63 if (bpos != std::string::npos) bpos = bpos - cpos;
64 keepPoolObj(persObj, pAddr->par()->substr(cpos, bpos));
65 // Update IOpaqueAddress for this object.
66 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
67 if (tokAddr != nullptr) {
68 tokAddr->setToken(std::move(token));
69 } else {
70 return(StatusCode::FAILURE);
71 }
72 return(status);
73}
74
75template <class TRANS, class PERS>
76StatusCode
77T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
78 const Token* token,
79 const std::string& key)
80{
81 std::lock_guard<AthenaPoolConverter::CallMutex> lock(this->m_conv_mut);
82 TRANS* transObj = nullptr;
83 AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
84 // reset the TP converter used for reading, so old value is not used
85 if (extCnv != nullptr) {
86 extCnv->resetTPCnvForReading();
87 }
88 try {
89 transObj = createTransientWithKey(token, key);
90 }
91 catch(const std::exception& ex) {
92 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
93 "creating transient object",
94 ex,
95 typeid(TRANS),
96 key);
97 }
98 if (extCnv != nullptr) {
99 extCnv->deletePersistentObjects();
100 }
101 pObj = SG::asStorable(transObj);
102 return(StatusCode::SUCCESS);
103}
104
105// Read object of type P. This is an exception-throwing version of poolToObject()
106// plus reading of all extending objects
107template <class TRANS, class PERS>
108template <class P>
109inline P* T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::poolReadObject(const Token* token) {
110 P* persObj = nullptr;
111 if (this->poolToObject(token, persObj).isFailure()) {
112 std::string error("POOL read failed. Token = ");
113 throw std::runtime_error(error + (token != nullptr ? token->toString() : ""));
114 }
115 AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
116 if (extCnv != nullptr) {
117 extCnv->readExtendingObjects(persObj);
118 }
119 return(persObj);
120}
121
122// Read object of type P (plus all extending objects)
123// using the indicated top-level TP converter
124template <class TRANS, class PERS>
125template <class P>
126inline void T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::poolReadObject(TopLevelTPCnvBase& tlp_converter, const Token* token) {
127 AthenaPoolCnvTPExtension *extCnv = dynamic_cast<AthenaPoolCnvTPExtension*>(this);
128 // set which Top level TP concerter will by used for reading
129 // only matters for extended converters
130 if (extCnv != nullptr) {
131 extCnv->usingTPCnvForReading(tlp_converter);
132 }
133 // read the object
134 P* persObj = poolReadObject<P>(token);
135 // remember the object we just read
136 tlp_converter.setTLPersObject(persObj);
137 // not returning the object - the TLP converter owns it now
138 // and it will delete it automatically in createTransient()!
139}
140
141// Remember the POOL object until commit (then delete it)
142template <class TRANS, class PERS>
143inline void T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::keepPoolObj(PERS* obj, const std::string& output) {
144 std::lock_guard lock(m_pListMutex);
145 (*m_persObjLists)[output].emplace_back(obj);
146}
147
148// callback from the CleanupSvc to delete persistent objects after commit
149template <class TRANS, class PERS>
150StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::cleanUp(const std::string& output) {
151 std::lock_guard lock(m_pListMutex);
152 (*m_persObjLists)[output].clear();
153 return(StatusCode::SUCCESS);
154}
155
156
157template <class TRANS, class PERS>
158PERS* T_AthenaPoolCustomCnv<TRANS, PERS>::createPersistentWithKey
159 (TRANS* obj, const std::string& /*key*/)
160{
161 return createPersistent(obj);
162}
163
164
165template <class TRANS, class PERS>
166TRANS* T_AthenaPoolCustomCnv<TRANS, PERS>::createTransientWithKey
167 (const Token* token, const std::string& /*key*/)
168{
169 return createTransient(token);
170}