2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5/** @file T_AthenaPoolCustomCnv.icc
6 * @brief This file contains the implementation for the templated T_AthenaPoolCustomCnv class.
7 * @author Marcin.Nowak@cern.ch
10#include "GaudiKernel/StatusCode.h"
11#include "GaudiKernel/DataObject.h"
12#include "GaudiKernel/IOpaqueAddress.h"
14#include "AthenaKernel/StorableConversions.h"
16#include "AthenaPoolCnvSvc/exceptions.h"
17#include "AthenaPoolCnvTPExtension.h"
21template <class TRANS, class PERS>
22T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::T_AthenaPoolCustomCnvWithKey(ISvcLocator* pSvcLocator,
23 const char* name /*= nullptr*/) : BaseType(pSvcLocator, name) {
26template <class TRANS, class PERS>
27StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::DataObjectToPool(IOpaqueAddress* pAddr, DataObject* pObj) {
28 ATH_MSG_VERBOSE("In DataObjectToPool() for key = " << pObj->name());
30 PERS* persObj = nullptr;
31 bool success = SG::fromStorable(pObj, obj);
32 if (!success || obj == nullptr) {
33 ATH_MSG_ERROR("Failed to cast DataObject to transient type");
34 return(StatusCode::FAILURE);
37 std::lock_guard<AthenaPoolConverter::CallMutex> lock(this->m_conv_mut);
38 persObj = createPersistentWithKey(obj, pObj->name());
40 catch (const std::exception& ex) {
41 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
42 "creating persistent object",
47 std::unique_ptr<Token> token;
48 StatusCode status = this->objectToPool(persObj, token, pObj->name(), *pAddr->par());
49 // Null/empty token means ERROR
50 if (token == nullptr || token->classID() == Guid::null()) {
51 ATH_MSG_ERROR("failed to get Token for " << pObj->name());
52 return(StatusCode::FAILURE);
54 std::size_t cpos = pAddr->par()->find(':');
55 std::size_t bpos = pAddr->par()->find('[');
56 if (cpos == std::string::npos) {
61 if (bpos != std::string::npos) bpos = bpos - cpos;
62 keepPoolObj(persObj, pAddr->par()->substr(cpos, bpos));
63 // Update IOpaqueAddress for this object.
64 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
65 if (tokAddr != nullptr) {
66 tokAddr->setToken(std::move(token));
68 return(StatusCode::FAILURE);
73template <class TRANS, class PERS>
75T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
77 const std::string& key)
79 std::lock_guard<AthenaPoolConverter::CallMutex> lock(this->m_conv_mut);
80 TRANS* transObj = nullptr;
81 AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
82 // reset the TP converter used for reading, so old value is not used
83 if (extCnv != nullptr) {
84 extCnv->resetTPCnvForReading();
87 transObj = createTransientWithKey(token, key);
89 catch(const std::exception& ex) {
90 AthenaPoolCnvSvc::throwExcCaughtException (__PRETTY_FUNCTION__,
91 "creating transient object",
96 if (extCnv != nullptr) {
97 extCnv->deletePersistentObjects();
99 pObj = SG::asStorable(transObj);
100 return(StatusCode::SUCCESS);
103// Read object of type P. This is an exception-throwing version of poolToObject()
104// plus reading of all extending objects
105template <class TRANS, class PERS>
107inline P* T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::poolReadObject(const Token* token) {
108 P* persObj = nullptr;
109 if (this->poolToObject(token, persObj).isFailure()) {
110 std::string error("POOL read failed. Token = ");
111 throw std::runtime_error(error + (token != nullptr ? token->toString() : ""));
113 AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
114 if (extCnv != nullptr) {
115 extCnv->readExtendingObjects(persObj);
120// Read object of type P (plus all extending objects)
121// using the indicated top-level TP converter
122template <class TRANS, class PERS>
124inline void T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::poolReadObject(TopLevelTPCnvBase& tlp_converter, const Token* token) {
125 AthenaPoolCnvTPExtension *extCnv = dynamic_cast<AthenaPoolCnvTPExtension*>(this);
126 // set which Top level TP concerter will by used for reading
127 // only matters for extended converters
128 if (extCnv != nullptr) {
129 extCnv->usingTPCnvForReading(tlp_converter);
132 P* persObj = poolReadObject<P>(token);
133 // remember the object we just read
134 tlp_converter.setTLPersObject(persObj);
135 // not returning the object - the TLP converter owns it now
136 // and it will delete it automatically in createTransient()!
139// Remember the POOL object until commit (then delete it)
140template <class TRANS, class PERS>
141inline void T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::keepPoolObj(PERS* obj, const std::string& output) {
142 std::lock_guard lock(m_pListMutex);
143 (*m_persObjLists)[output].emplace_back(obj);
146// callback from the CleanupSvc to delete persistent objects after commit
147template <class TRANS, class PERS>
148StatusCode T_AthenaPoolCustomCnvWithKey<TRANS, PERS>::cleanUp(const std::string& output) {
149 std::lock_guard lock(m_pListMutex);
150 (*m_persObjLists)[output].clear();
151 return(StatusCode::SUCCESS);
155template <class TRANS, class PERS>
156PERS* T_AthenaPoolCustomCnv<TRANS, PERS>::createPersistentWithKey
157 (TRANS* obj, const std::string& /*key*/)
159 return createPersistent(obj);
163template <class TRANS, class PERS>
164TRANS* T_AthenaPoolCustomCnv<TRANS, PERS>::createTransientWithKey
165 (const Token* token, const std::string& /*key*/)
167 return createTransient(token);