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