ATLAS Offline Software
Loading...
Searching...
No Matches
AthenaPoolSharedIOCnvSvc Class Reference

This class provides the interface between Athena and PoolSvc. More...

#include <AthenaPoolSharedIOCnvSvc.h>

Inheritance diagram for AthenaPoolSharedIOCnvSvc:
Collaboration diagram for AthenaPoolSharedIOCnvSvc:

Public Member Functions

virtual StatusCode initialize () override
 Required of all Gaudi Services.
virtual StatusCode finalize () override
 Required of all Gaudi Services.
virtual StatusCode connectOutput (const std::string &outputConnectionSpec, const std::string &openMode) override
 Implementation of IConversionSvc: Connect to the output connection specification with open mode.
virtual StatusCode connectOutput (const std::string &outputConnectionSpec) override
 Implementation of IConversionSvc: Connect to the output connection specification with open mode.
virtual StatusCode commitOutput (const std::string &outputConnectionSpec, bool doCommit) override
 Implementation of IConversionSvc: Commit pending output.
virtual StatusCode disconnectOutput (const std::string &outputConnectionSpec) override
 Disconnect to the output connection.
virtual TokenregisterForWrite (Placement *placement, const void *obj, const RootType &classDesc) override
virtual void setObjPtr (void *&obj, const Token *token) override
StatusCode createAddress (long svcType, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
 Create a Generic address using explicit arguments to identify a single object.
virtual StatusCode createAddress (long svcType, const CLID &clid, const std::string &refAddress, IOpaqueAddress *&refpAddress) override
 Create address from string form.
virtual StatusCode cleanUp (const std::string &connection) override
 Implement cleanUp to call all registered IAthenaPoolCleanUp cleanUp() function.
virtual StatusCode makeServer (int num) override
 Make this a server.
virtual StatusCode makeClient (int num) override
 Make this a client.
virtual StatusCode readData () override
 Read the next data object.
virtual StatusCode commitCatalog () override
 Commit Catalog.
StatusCode abortSharedWrClients (int client_n)
 Send abort to SharedWriter clients if the server quits on error.
virtual void handle (const Incident &incident) override
 Implementation of IIncidentListener: Handle for EndEvent incidence.
 AthenaPoolSharedIOCnvSvc (const std::string &name, ISvcLocator *pSvcLocator)
 Standard Service Constructor.
virtual ~AthenaPoolSharedIOCnvSvc ()
 Destructor.

Private Attributes

ServiceHandle< IAthenaSerializeSvcm_serializeSvc {this,"AthenaRootSerializeSvc","AthenaRootSerializeSvc"}
std::unique_ptr< RootAuxDynIO::IFactoryToolm_auxDynTool
ToolHandle< IAthenaIPCToolm_inputStreamingTool {this,"InputStreamingTool",{}}
std::unique_ptr< RootAuxDynIO::IAuxDynSharem_auxInput
ToolHandle< IAthenaIPCToolm_outputStreamingTool {this,"OutputStreamingTool",{}}
std::unique_ptr< RootAuxDynIO::IAuxDynSharem_auxOutput
bool m_streamServerActive =false
int m_metadataClient =0
Gaudi::Property< std::string > m_metadataContainerProp {this,"OutputMetadataContainer","MetaData"}
 For SharedWriter: To use MetadataSvc to merge data placed in a certain container.
Gaudi::Property< std::vector< std::string > > m_metadataContainersAug {this, "OutputMetadataContainers", {}, "Metadata containers used for augmentations"}
Gaudi::Property< int > m_makeStreamingToolClient {this,"MakeStreamingToolClient",0}
 Make this instance a Streaming Client during first connect/write automatically.
Gaudi::Property< int > m_streamingTechnology {this,"StreamingTechnology",-1}
 Use Streaming for selected technologies only.
Gaudi::Property< bool > m_parallelCompression {this,"ParallelCompression",true}
 Use Athena Object sharing for metadata only, event data is collected and send via ROOT TMemFile.
Gaudi::Property< std::string > m_streamPortString {this,"StreamPortString","?pmerge=localhost:0"}
 Extension to use ROOT TMemFile for event data, "?pmerge=<host>:<port>".
std::map< std::string, int > m_fileCommitCounter
 Force SharedWriter to flush data to output file at given intervals, needed by parallel compression.
Gaudi::Property< std::map< std::string, int > > m_fileFlushSetting {this,"FileFlushSetting",{}}

Friends

class SvcFactory< AthenaPoolSharedIOCnvSvc >

Detailed Description

This class provides the interface between Athena and PoolSvc.

Definition at line 30 of file AthenaPoolSharedIOCnvSvc.h.

Constructor & Destructor Documentation

◆ AthenaPoolSharedIOCnvSvc()

AthenaPoolSharedIOCnvSvc::AthenaPoolSharedIOCnvSvc ( const std::string & name,
ISvcLocator * pSvcLocator )

Standard Service Constructor.

Definition at line 872 of file AthenaPoolSharedIOCnvSvc.cxx.

872 :
873 base_class(name, pSvcLocator) {
874}

◆ ~AthenaPoolSharedIOCnvSvc()

AthenaPoolSharedIOCnvSvc::~AthenaPoolSharedIOCnvSvc ( )
virtual

Destructor.

Definition at line 876 of file AthenaPoolSharedIOCnvSvc.cxx.

876 {
877}

Member Function Documentation

◆ abortSharedWrClients()

StatusCode AthenaPoolSharedIOCnvSvc::abortSharedWrClients ( int client_n)

Send abort to SharedWriter clients if the server quits on error.

Parameters
client_n[IN] number of the current client, -1 if no current

Definition at line 846 of file AthenaPoolSharedIOCnvSvc.cxx.

847{
848 ATH_MSG_ERROR("Sending ABORT to clients");
849 // the master process will kill this process once workers abort
850 // but it could be a time-limited loop
851 StatusCode sc = StatusCode::SUCCESS;
852 while (sc.isSuccess()) {
853 if (client_n >= 0) {
854 sc = m_outputStreamingTool->lockObject("ABORT", client_n);
855 }
856 const char* dummy;
857 sc = m_outputStreamingTool->clearObject(&dummy, client_n);
858 while (sc.isRecoverable()) {
859 sc = m_outputStreamingTool->clearObject(&dummy, client_n);
860 }
861 }
862 return StatusCode::FAILURE;
863}
#define ATH_MSG_ERROR(x)
static Double_t sc
ToolHandle< IAthenaIPCTool > m_outputStreamingTool
::StatusCode StatusCode
StatusCode definition for legacy code.

◆ cleanUp()

StatusCode AthenaPoolSharedIOCnvSvc::cleanUp ( const std::string & connection)
overridevirtual

Implement cleanUp to call all registered IAthenaPoolCleanUp cleanUp() function.

Definition at line 714 of file AthenaPoolSharedIOCnvSvc.cxx.

714 {
715 auto pos = connection.find("?pmerge=");
716 std::string conn = (pos == std::string::npos) ? connection : connection.substr(0, pos);
717 return AthenaPoolCnvSvc::cleanUp(conn);
718}
virtual StatusCode cleanUp(const std::string &connection) override
Implement cleanUp to call all registered IAthenaPoolCleanUp cleanUp() function.

◆ commitCatalog()

StatusCode AthenaPoolSharedIOCnvSvc::commitCatalog ( )
overridevirtual

Commit Catalog.

Definition at line 839 of file AthenaPoolSharedIOCnvSvc.cxx.

839 {
840 getPoolSvc()->commitCatalog();
841 getPoolSvc()->startCatalog();
842 return(StatusCode::SUCCESS);
843}

◆ commitOutput()

StatusCode AthenaPoolSharedIOCnvSvc::commitOutput ( const std::string & outputConnectionSpec,
bool doCommit )
overridevirtual

Implementation of IConversionSvc: Commit pending output.

Parameters
doCommit[IN] boolean to force full commit

Definition at line 137 of file AthenaPoolSharedIOCnvSvc.cxx.

137 {
138 // This is called after all DataObjects are converted.
139 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
140 if (!m_outputStreamingTool.empty() && m_outputStreamingTool->isClient()
141 && (!m_parallelCompression || outputConnectionSpec.find("[PoolContainerPrefix=" + m_metadataContainerProp.value() + "]") != std::string::npos)) {
142 m_outputStreamingTool->lockObject("wait").ignore();
143 if (!this->cleanUp(outputConnection).isSuccess()) {
144 ATH_MSG_ERROR("commitOutput FAILED to cleanup converters.");
145 return(StatusCode::FAILURE);
146 }
147 return(StatusCode::SUCCESS);
148 }
149 if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient() && !m_outputStreamingTool->isServer()) {
150 ATH_MSG_DEBUG("commitOutput SKIPPED for uninitialized server.");
151 return(StatusCode::SUCCESS);
152 }
153 std::map<void*, RootType> commitCache;
154 std::string fileName;
155 if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient() && m_outputStreamingTool->isServer() && m_streamServerActive) {
156 // Clear object to get Placements for all objects in a Stream
157 const char* placementStr = nullptr;
158 int num = -1;
159 StatusCode sc = m_outputStreamingTool->clearObject(&placementStr, num);
160 if (sc.isSuccess() && placementStr != nullptr && strlen(placementStr) > 6 && num > 0) {
161 const char * matchedChars = strstr(placementStr, "[FILE=");
162 if (!matchedChars){
163 ATH_MSG_ERROR(std::format("No matching filename in {}", placementStr));
164 return abortSharedWrClients(num);
165 }
166 fileName = matchedChars;
167 fileName = fileName.substr(6, fileName.find(']') - 6);
168 if (!this->connectOutput(fileName).isSuccess()) {
169 ATH_MSG_ERROR(std::format("Failed to connectOutput for {}", fileName));
170 return abortSharedWrClients(num);
171 }
172 IConverter* DHcnv = converter(ClassID_traits<DataHeader>::ID());
173 bool dataHeaderSeen = false;
174 std::string dataHeaderID;
175 while (num > 0) {
176 std::string objName = "ALL";
177 if (useDetailChronoStat()) {
178 objName = placementStr; //FIXME, better descriptor
179 }
180 // StopWatch listens from here until the end of this current scope
181 {
182 PMonUtils::BasicStopWatch stopWatch("cRep_" + objName, this->m_chronoMap);
183 std::string_view pStr = placementStr;
184 std::string::size_type cpos = pStr.find ("[CONT=");
185 if (cpos == std::string::npos) {
186 ATH_MSG_ERROR(std::format("No CONT field in placement string: {}", pStr));
187 return StatusCode::FAILURE;
188 }
189 std::string tokenStr (pStr.substr(0, cpos));
190 std::string contName (pStr.substr(cpos, std::string::npos));
191 std::string::size_type cl1 = contName.find(']');
192 if (cl1 == std::string::npos) {
193 ATH_MSG_ERROR(std::format("Missing close bracket after CONT field in placement string: {}", pStr));
194 return StatusCode::FAILURE;
195 }
196 tokenStr.append(contName, cl1 + 1);
197 contName = contName.substr(6, cl1 - 6);
198
199 std::string::size_type ppos = pStr.find ("[PNAME=");
200 if (ppos == std::string::npos) {
201 ATH_MSG_ERROR(std::format("No PNAME field in placement string: {}", pStr));
202 return StatusCode::FAILURE;
203 }
204 std::string className (pStr.substr(ppos, std::string::npos));
205 std::string::size_type cl2 = className.find(']');
206 if (cl2 == std::string::npos) {
207 ATH_MSG_ERROR(std::format("Missing close bracket after PNAME field in placement string: {}", pStr));
208 return StatusCode::FAILURE;
209 }
210 className = className.substr(7, cl2 - 7);
211 RootType classDesc = RootType::ByNameNoQuiet(className);
212 void* obj = nullptr;
213 const std::string numStr = std::to_string(num);
214 std::string::size_type len = m_metadataContainerProp.value().size();
215 bool foundContainer = false;
216 std::size_t opPos = contName.find('(');
217 if (contName.compare(0, opPos, m_metadataContainerProp.value()) == 0) {
218 foundContainer = true;
219 } else {
220 for (const auto& item: m_metadataContainersAug.value()) {
221 if (contName.compare(0, opPos, item) == 0){
222 foundContainer = true;
223 len = item.size();
224 break;
225 }
226 }
227 }
228 if (len > 0 && foundContainer && contName[len] == '(' ) {
229 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", name());
230 // For Metadata, before moving to next client, fire file incidents
231 if (m_metadataClient != num) {
232 if (m_metadataClient != 0) {
233 std::string memName = std::format("SHM[NUM={}]", m_metadataClient);
234 auto guard = InputFileIncidentGuard::begin(*incSvc, name(),
235 memName, {}, /*endFileName=*/memName,
236 "BeginInputMemFile", "EndInputMemFile");
237 }
239 }
240 // Retrieve MetaDataSvc
241 ServiceHandle<IAthMetaDataSvc> metadataSvc("MetaDataSvc", name());
242 ATH_CHECK(metadataSvc.retrieve());
243 sc = metadataSvc->shmProxy(std::format("{}[NUM={}]", pStr, numStr));
244 if (sc.isRecoverable()) {
245 ATH_MSG_WARNING("MetaDataSvc::shmProxy() no proxy added.");
246 } else if (sc.isFailure()) {
247 ATH_MSG_FATAL("MetaDataSvc::shmProxy() failed!");
248 return abortSharedWrClients(num);
249 }
250 } else {
251 Token readToken;
252 readToken.setOid(Token::OID_t(num, 0));
253 readToken.setAuxString("[PNAME=" + className + "]");
254 this->setObjPtr(obj, &readToken); // Pull/read Object out of shared memory
255 if (len == 0 || contName.compare(0, len, m_metadataContainerProp.value()) != 0) {
256 // Write object
257 if( m_oneDataHeaderForm.value() ) {
258 auto placementWithSwn = [&] { return std::format("{}[SWN={}]", placementStr, num); };
259 if( className == "DataHeaderForm_p6" ) {
260 // Pass DHForms to the converter for later writing in the correct order - do not write it now
262 "", placementWithSwn());
263 DHcnv->updateRepRefs(&address, static_cast<DataObject*>(obj)).ignore();
264 tokenStr = "";
265 } else {
266 Placement placement;
267 placement.fromString(placementStr);
268 std::unique_ptr<Token> token(registerForWrite(&placement, obj, classDesc));
269 if (token == nullptr) {
270 ATH_MSG_ERROR("Failed to write Data for: " << className);
271 return abortSharedWrClients(num);
272 }
273 tokenStr = token->toString();
274 }
275 if( className == "DataHeader_p6" ) {
276 // Found DataHeader - call the converter to update DHForm Ref
278 tokenStr, placementWithSwn());
279 if (!DHcnv->updateRep(&address, static_cast<DataObject*>(obj)).isSuccess()) {
280 ATH_MSG_ERROR("Failed updateRep for obj = " << tokenStr);
281 return abortSharedWrClients(num);
282 }
283 } else
284 if (className != "Token" && className != "DataHeaderForm_p6" && !classDesc.IsFundamental()) {
285 commitCache.insert(std::pair<void*, RootType>(obj, classDesc));
286 }
287 placementStr = nullptr;
288 } else {
289 // Multiple shared DataHeaderForms
290 Placement placement;
291 placement.fromString(placementStr); placementStr = nullptr;
292 std::unique_ptr<Token> token(registerForWrite(&placement, obj, classDesc));
293 if (token == nullptr) {
294 ATH_MSG_ERROR("Failed to write Data for: " << className);
295 return abortSharedWrClients(num);
296 }
297 tokenStr = token->toString();
298 if (className == "DataHeader_p6") {
299 // Found DataHeader
301 tokenStr, placement.auxString());
302 // call DH converter to add the ref to DHForm (stored earlier) and to itself
303 if (!DHcnv->updateRep(&address, static_cast<DataObject*>(obj)).isSuccess()) {
304 ATH_MSG_ERROR("Failed updateRep for obj = " << tokenStr);
305 return abortSharedWrClients(num);
306 }
307 dataHeaderSeen = true;
308 // This dataHeaderID is used in DataHeaderCnv to index the DataHeaderForm cache.
309 // It must be unique per worker per stream so that we have a correct DataHeader(Form) association.
310 // This is achieved by building it as "CONTID/WORKERID/DBID".
311 // CONTID, e.g., POOLContainer(DataHeader), allows us to distinguish data and metadata headers,
312 // WORKERID allows us to distinguish AthenaMP workers,
313 // and DBID allows us to distinguish streams.
314 dataHeaderID = std::format("{}/{}/{}", token->contID(), numStr, token->dbID().toString());
315 } else if (dataHeaderSeen) {
316 dataHeaderSeen = false;
317 // next object after DataHeader - may be a DataHeaderForm
318 // in any case we need to call the DH converter to update the DHForm Ref
319 if (className == "DataHeaderForm_p6") {
320 // Tell DataHeaderCnv that it should use a new DHForm
322 tokenStr, dataHeaderID);
323 if (!DHcnv->updateRepRefs(&address, static_cast<DataObject*>(obj)).isSuccess()) {
324 ATH_MSG_ERROR("Failed updateRepRefs for obj = " << tokenStr);
325 return abortSharedWrClients(num);
326 }
327 } else {
328 // Tell DataHeaderCnv that it should use the old DHForm
329 GenericAddress address(0, 0, "", dataHeaderID);
330 if (!DHcnv->updateRepRefs(&address, nullptr).isSuccess()) {
331 ATH_MSG_ERROR("Failed updateRepRefs for DataHeader");
332 return abortSharedWrClients(num);
333 }
334 }
335 }
336 if (className != "Token" && className != "DataHeaderForm_p6" && !classDesc.IsFundamental()) {
337 commitCache.insert(std::pair<void*, RootType>(obj, classDesc));
338 }
339 }
340 }
341 }
342 // Send Token back to Client
343 sc = m_outputStreamingTool->lockObject(tokenStr.c_str(), num);
344 while (sc.isRecoverable()) {
345 sc = m_outputStreamingTool->lockObject(tokenStr.c_str(), num);
346 }
347 if (!sc.isSuccess()) {
348 ATH_MSG_ERROR("Failed to lock Data for " << tokenStr);
349 return abortSharedWrClients(-1);
350 }
351 }
352 sc = m_outputStreamingTool->clearObject(&placementStr, num);
353 while (sc.isRecoverable()) {
354 sc = m_outputStreamingTool->clearObject(&placementStr, num);
355 }
356 if (sc.isFailure()) {
357 // no more clients, break the loop and exit
358 num = -1;
359 }
360 }
361 if (dataHeaderSeen) {
362 // DataHeader was the last object, need to tell the converter there is no DHForm coming
363 GenericAddress address(0, 0, "", std::move(dataHeaderID));
364 if (!DHcnv->updateRepRefs(&address, nullptr).isSuccess()) {
365 ATH_MSG_ERROR("Failed updateRepRefs for DataHeader");
366 return abortSharedWrClients(-1);
367 }
368 }
369 placementStr = nullptr;
370 } else if (sc.isSuccess() && placementStr != nullptr && strncmp(placementStr, "stop", 4) == 0) {
371 return(StatusCode::RECOVERABLE);
372 } else if (sc.isRecoverable() || num == -1) {
373 return(StatusCode::RECOVERABLE);
374 }
375 if (sc.isFailure() || fileName.empty()) {
376 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", name());
377 std::string memName = std::format("SHM[NUM={}]", m_metadataClient);
378 {
379 auto guard = InputFileIncidentGuard::begin(*incSvc, name(),
380 memName, {}, /*endFileName=*/memName,
381 "BeginInputMemFile", "EndInputMemFile");
382 }
383 if (sc.isFailure()) {
384 ATH_MSG_INFO("All SharedWriter clients stopped - exiting");
385 } else {
386 ATH_MSG_INFO("Failed to get Data for client: " << num);
387 }
388 return(StatusCode::FAILURE);
389 }
390 }
391 if (m_parallelCompression && !fileName.empty()) {
392 ATH_MSG_DEBUG(std::format("commitOutput SKIPPED for metadata-only server: {}", outputConnectionSpec));
393 return(StatusCode::SUCCESS);
394 }
395 if (outputConnection.empty()) {
396 outputConnection = std::move(fileName);
397 } else {
398 outputConnection = outputConnectionSpec;
400 outputConnection += m_streamPortString.value();
401 }
402 }
403 std::size_t merge = outputConnection.find("?pmerge="); // Used to remove trailing TMemFile
404 const std::string baseOutputConnection = outputConnection.substr(0, merge);
405 m_fileCommitCounter[baseOutputConnection]++;
407 m_fileFlushSetting.value().contains(baseOutputConnection) &&
408 m_fileFlushSetting[baseOutputConnection] > 0 &&
409 m_fileCommitCounter[baseOutputConnection] % m_fileFlushSetting[baseOutputConnection] == 0) {
410 doCommit = true;
411 ATH_MSG_DEBUG("commitOutput sending data.");
412 }
413 StatusCode status = AthenaPoolCnvSvc::commitOutput(outputConnection, doCommit);
414 for (auto& [ptr, rootType] : commitCache) {
415 rootType.Destruct(ptr);
416 }
417 return(status);
418}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
TTypeAdapter RootType
Definition RootType.h:211
bool merge(const StringPool &other)
Merge another pool into this one.
virtual StatusCode commitOutput(const std::string &outputConnectionSpec, bool doCommit) override
Implementation of IConversionSvc: Commit pending output.
std::map< std::string, int > m_fileCommitCounter
Force SharedWriter to flush data to output file at given intervals, needed by parallel compression.
Gaudi::Property< std::string > m_streamPortString
Extension to use ROOT TMemFile for event data, "?pmerge=<host>:<port>".
virtual StatusCode cleanUp(const std::string &connection) override
Implement cleanUp to call all registered IAthenaPoolCleanUp cleanUp() function.
virtual void setObjPtr(void *&obj, const Token *token) override
StatusCode abortSharedWrClients(int client_n)
Send abort to SharedWriter clients if the server quits on error.
Gaudi::Property< std::string > m_metadataContainerProp
For SharedWriter: To use MetadataSvc to merge data placed in a certain container.
virtual StatusCode connectOutput(const std::string &outputConnectionSpec, const std::string &openMode) override
Implementation of IConversionSvc: Connect to the output connection specification with open mode.
Gaudi::Property< std::vector< std::string > > m_metadataContainersAug
Gaudi::Property< bool > m_parallelCompression
Use Athena Object sharing for metadata only, event data is collected and send via ROOT TMemFile.
Gaudi::Property< std::map< std::string, int > > m_fileFlushSetting
virtual Token * registerForWrite(Placement *placement, const void *obj, const RootType &classDesc) override
static InputFileIncidentGuard begin(IIncidentSvc &incSvc, std::string_view source, std::string_view beginFileName, std::string_view guid, std::string_view endFileName={}, std::string_view beginType=IncidentType::BeginInputFile, std::string_view endType=IncidentType::EndInputFile)
Factory: fire the begin incident and return a guard whose destructor fires the matching end incident.
const std::string & auxString() const
Access auxiliary string.
Definition Placement.h:41
Placement & fromString(const std::string &from)
Build from the string representation of a placement.
Definition Placement.cxx:28
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition RootType.cxx:586
Bool_t IsFundamental() const
Definition RootType.cxx:731
Token & setOid(const OID_t &oid)
Set object identifier.
Definition Token.h:86
Token & setAuxString(std::string &&auxString)
Set auxiliary string.
Definition Token.h:94
status
Definition merge.py:16
static const DbType POOL_StorageType
Definition DbType.h:84
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.

◆ connectOutput() [1/2]

StatusCode AthenaPoolSharedIOCnvSvc::connectOutput ( const std::string & outputConnectionSpec)
overridevirtual

Implementation of IConversionSvc: Connect to the output connection specification with open mode.

Parameters
outputConnectionSpec[IN] the name of the output connection specification as string.

Definition at line 100 of file AthenaPoolSharedIOCnvSvc.cxx.

100 {
101// This is called before DataObjects are being converted.
102 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
103 if (m_makeStreamingToolClient.value() > 0 && !m_outputStreamingTool.empty() && !m_outputStreamingTool->isServer() && !m_outputStreamingTool->isClient()) {
104 if (!makeClient(m_makeStreamingToolClient.value()).isSuccess()) {
105 ATH_MSG_ERROR("Could not make AthenaPoolSharedIOCnvSvc a Share Client");
106 return(StatusCode::FAILURE);
107 }
108 }
109 if (!m_outputStreamingTool.empty() && m_outputStreamingTool->isClient()
110 && (!m_parallelCompression || outputConnectionSpec.find("[PoolContainerPrefix=" + m_metadataContainerProp.value() + "]") != std::string::npos)) {
111 return(StatusCode::SUCCESS);
112 }
113 if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient()) {
114 if (m_parallelCompression && outputConnectionSpec.find("[PoolContainerPrefix=" + m_metadataContainerProp.value() + "]") == std::string::npos) {
115 ATH_MSG_DEBUG(std::format("connectOutput SKIPPED for metadata-only server: {}", outputConnectionSpec));
116 return(StatusCode::SUCCESS);
117 }
119 ATH_MSG_DEBUG("connectOutput SKIPPED for expired server.");
120 return(StatusCode::SUCCESS);
121 }
122 }
124 outputConnection += m_streamPortString.value();
125 }
126 std::size_t apend = outputConnectionSpec.find('[');
127 if (apend != std::string::npos) {
128 outputConnection += outputConnectionSpec.substr(apend);
129 }
130 if (outputConnectionSpec.find("[PoolContainerPrefix=" + m_metadataContainerProp.value() + "]") != std::string::npos) {
131 return AthenaPoolCnvSvc::connectOutput(outputConnection, "APPEND");
132 }
133 return AthenaPoolCnvSvc::connectOutput(outputConnection);
134}
virtual StatusCode connectOutput(const std::string &outputConnectionSpec, const std::string &openMode) override
Implementation of IConversionSvc: Connect to the output connection specification with open mode.
Gaudi::Property< int > m_makeStreamingToolClient
Make this instance a Streaming Client during first connect/write automatically.
virtual StatusCode makeClient(int num) override
Make this a client.

◆ connectOutput() [2/2]

StatusCode AthenaPoolSharedIOCnvSvc::connectOutput ( const std::string & outputConnectionSpec,
const std::string & openMode )
overridevirtual

Implementation of IConversionSvc: Connect to the output connection specification with open mode.

Parameters
outputConnectionSpec[IN] the name of the output connection specification as string.
openMode[IN] the open mode of the file as string.

Definition at line 95 of file AthenaPoolSharedIOCnvSvc.cxx.

96 {
97 return AthenaPoolCnvSvc::connectOutput(outputConnectionSpec, openMode);
98}

◆ createAddress() [1/2]

StatusCode AthenaPoolSharedIOCnvSvc::createAddress ( long svcType,
const CLID & clid,
const std::string & refAddress,
IOpaqueAddress *& refpAddress )
overridevirtual

Create address from string form.

Parameters
svcType[IN] service type of the address.
clid[IN] class id for the address.
refAddress[IN] string form to be converted.
refpAddress[OUT] converted address.

Definition at line 707 of file AthenaPoolSharedIOCnvSvc.cxx.

710 {
711 return AthenaPoolCnvSvc::createAddress(svcType, clid, refAddress, refpAddress);
712}
StatusCode createAddress(long svcType, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
Create a Generic address using explicit arguments to identify a single object.

◆ createAddress() [2/2]

StatusCode AthenaPoolSharedIOCnvSvc::createAddress ( long svcType,
const CLID & clid,
const std::string * par,
const unsigned long * ip,
IOpaqueAddress *& refpAddress )
override

Create a Generic address using explicit arguments to identify a single object.

Parameters
svcType[IN] service type of the address.
clid[IN] class id for the address.
par[IN] string containing the database name.
ip[IN] object identifier.
refpAddress[OUT] converted address.

Definition at line 664 of file AthenaPoolSharedIOCnvSvc.cxx.

668 {
669 if (m_makeStreamingToolClient.value() > 0 && !m_inputStreamingTool.empty() && !m_inputStreamingTool->isServer() && !m_inputStreamingTool->isClient()) {
671 }
672 if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient()) {
673 Token addressToken;
674 addressToken.setDb(par[0].substr(4));
675 addressToken.setCont(par[1]);
676 addressToken.setOid(Token::OID_t(ip[0], ip[1]));
677 ATH_CHECK(m_inputStreamingTool->lockObject(addressToken.toString().c_str()));
678 void* buffer = nullptr;
679 std::size_t nbytes = 0;
680 StatusCode sc = m_inputStreamingTool->getObject(&buffer, nbytes);
681 while (sc.isRecoverable()) {
682 // sleep
683 sc = m_inputStreamingTool->getObject(&buffer, nbytes);
684 }
685 if (!sc.isSuccess()) {
686 ATH_MSG_WARNING("Failed to get Address Token: " << addressToken.toString());
687 return(StatusCode::FAILURE);
688 }
689 auto token = std::make_unique<Token>();
690 token->fromString(static_cast<const char*>(buffer)); buffer = nullptr;
691 if (token->classID() == Guid::null()) {
692 token.reset();
693 }
694 m_inputStreamingTool->getObject(&buffer, nbytes).ignore();
695 if (token) {
696 refpAddress = new TokenAddress(pool::POOL_StorageType.type(), clid, "", par[1], IPoolSvc::kInputStream, std::move(token));
697 return(StatusCode::SUCCESS);
698 }
699 else {
700 return(StatusCode::RECOVERABLE);
701 }
702 } else {
703 return AthenaPoolCnvSvc::createAddress(svcType, clid, par, ip, refpAddress);
704 }
705}
ToolHandle< IAthenaIPCTool > m_inputStreamingTool
static const Guid & null() noexcept
NULL-Guid: static class method.
Definition Guid.cxx:14
@ kInputStream
Definition IPoolSvc.h:37
Token & setCont(const std::string &cnt)
Set container name.
Definition Token.h:72
Token & setDb(const Guid &db)
Set database name.
Definition Token.h:67
const std::string toString() const
Retrieve the string representation of the token.
Definition Token.cxx:135

◆ disconnectOutput()

StatusCode AthenaPoolSharedIOCnvSvc::disconnectOutput ( const std::string & outputConnectionSpec)
overridevirtual

Disconnect to the output connection.

Definition at line 421 of file AthenaPoolSharedIOCnvSvc.cxx.

421 {
422 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
423 if (!m_outputStreamingTool.empty() && m_outputStreamingTool->isClient()
424 && (!m_parallelCompression || outputConnectionSpec.find("[PoolContainerPrefix=" + m_metadataContainerProp.value() + "]") != std::string::npos)) {
425 return(StatusCode::SUCCESS);
426 }
427 if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient()) {
429 m_streamServerActive = false;
430 ATH_MSG_DEBUG("disconnectOutput SKIPPED to expire server.");
431 return(StatusCode::SUCCESS);
432 } else {
433 m_streamServerActive = false;
434 }
435 ATH_MSG_DEBUG("disconnectOutput not SKIPPED for server.");
436 }
438 outputConnection += m_streamPortString.value();
439 }
440 return AthenaPoolCnvSvc::disconnectOutput(outputConnectionSpec + m_streamPortString.value());
441}
virtual StatusCode disconnectOutput(const std::string &outputConnectionSpec) override
Disconnect to the output connection.

◆ finalize()

StatusCode AthenaPoolSharedIOCnvSvc::finalize ( )
overridevirtual

Required of all Gaudi Services.

Definition at line 73 of file AthenaPoolSharedIOCnvSvc.cxx.

73 {
74 // Release AthenaSerializeSvc
75 if (!m_serializeSvc.empty()) {
76 if (!m_serializeSvc.release().isSuccess()) {
77 ATH_MSG_WARNING("Cannot release AthenaSerializeSvc.");
78 }
79 }
80 // Release OutputStreamingTool (if configured)
81 if (!m_outputStreamingTool.empty()) {
82 if (!m_outputStreamingTool.release().isSuccess()) {
83 ATH_MSG_WARNING("Cannot release Output AthenaIPCTool.");
84 }
85 }
86 // Release InputStreamingTool (if configured)
87 if (!m_inputStreamingTool.empty()) {
88 if (!m_inputStreamingTool.release().isSuccess()) {
89 ATH_MSG_WARNING("Cannot release Input AthenaIPCTool.");
90 }
91 }
92 return this->AthenaPoolCnvSvc::finalize();
93}
virtual StatusCode finalize() override
Required of all Gaudi Services.
ServiceHandle< IAthenaSerializeSvc > m_serializeSvc

◆ handle()

void AthenaPoolSharedIOCnvSvc::handle ( const Incident & incident)
overridevirtual

Implementation of IIncidentListener: Handle for EndEvent incidence.

Definition at line 866 of file AthenaPoolSharedIOCnvSvc.cxx.

866 {
867 if (incident.type() == "StoreCleared" && m_outputStreamingTool->isClient() && !m_parallelCompression) {
868 m_outputStreamingTool->lockObject("release").ignore();
869 }
870}

◆ initialize()

StatusCode AthenaPoolSharedIOCnvSvc::initialize ( )
overridevirtual

Required of all Gaudi Services.

Definition at line 38 of file AthenaPoolSharedIOCnvSvc.cxx.

38 {
39 if (!m_inputStreamingTool.empty() || !m_outputStreamingTool.empty()) {
40 // Retrieve AthenaSerializeSvc
41 ATH_CHECK(m_serializeSvc.retrieve());
42 m_auxDynTool = Gaudi::PluginService::Factory< RootAuxDynIO::IFactoryTool*() >::create("RootAuxDynIO::FactoryTool");
43 if (!m_auxDynTool) {
44 return StatusCode::FAILURE;
45 }
46 }
47 // Retrieve InputStreamingTool (if configured)
48 if (!m_inputStreamingTool.empty()) {
50 m_auxInput = m_auxDynTool->getAuxDynShare(m_serializeSvc.get(), m_inputStreamingTool.get());
51 }
52 // Retrieve OutputStreamingTool (if configured)
53 if (!m_outputStreamingTool.empty()) {
55 m_auxOutput = m_auxDynTool->getAuxDynShare(m_serializeSvc.get(), m_outputStreamingTool.get());
56 if (m_makeStreamingToolClient.value() == -1) {
57 // Initialize AthenaRootSharedWriter
58 ServiceHandle<IService> arswsvc("AthenaRootSharedWriterSvc", this->name());
59 ATH_CHECK(arswsvc.retrieve());
60 }
61 // Put PoolSvc into share mode to avoid duplicating catalog.
62 getPoolSvc()->setShareMode(true);
63 }
64 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", name());
65 long int pri = 1000;
66 if (!m_outputStreamingTool.empty()) {
67 incSvc->addListener(this, "StoreCleared", pri);
68 ATH_MSG_DEBUG("Subscribed to StoreCleared");
69 }
70 return this->AthenaPoolCnvSvc::initialize();
71}
virtual StatusCode initialize() override
Required of all Gaudi Services.
std::unique_ptr< RootAuxDynIO::IAuxDynShare > m_auxOutput
std::unique_ptr< RootAuxDynIO::IAuxDynShare > m_auxInput
std::unique_ptr< RootAuxDynIO::IFactoryTool > m_auxDynTool

◆ makeClient()

StatusCode AthenaPoolSharedIOCnvSvc::makeClient ( int num)
overridevirtual

Make this a client.

Definition at line 746 of file AthenaPoolSharedIOCnvSvc.cxx.

746 {
747 if (!m_outputStreamingTool.empty()) {
748 ATH_MSG_DEBUG("makeClient: " << m_outputStreamingTool << " = " << num);
749 std::string streamPortSuffix;
750 if (m_outputStreamingTool->makeClient(num, streamPortSuffix).isFailure()) {
751 ATH_MSG_ERROR("makeClient: " << m_outputStreamingTool << " failed");
752 return(StatusCode::FAILURE);
753 } else if (m_streamPortString.value().find("localhost:0") != std::string::npos) {
754 // We don't seem to use a dedicated port per stream so doing this for the first client is probably OK
755 ATH_MSG_DEBUG("makeClient: Setting conversion service port suffix to " << streamPortSuffix);
756 m_streamPortString.setValue(streamPortSuffix);
757 }
758 }
759 if (m_inputStreamingTool.empty()) {
760 return(StatusCode::SUCCESS);
761 }
762 ATH_MSG_DEBUG("makeClient: " << m_inputStreamingTool << " = " << num);
763 std::string dummyStr;
764 return(m_inputStreamingTool->makeClient(num, dummyStr));
765}

◆ makeServer()

StatusCode AthenaPoolSharedIOCnvSvc::makeServer ( int num)
overridevirtual

Make this a server.

Definition at line 720 of file AthenaPoolSharedIOCnvSvc.cxx.

720 {
721 if (num < 0) {
722 num = -num;
724 num = num % 1024;
725 if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isServer()) {
726 ATH_MSG_DEBUG(std::format("makeServer: {} = {}", m_outputStreamingTool.name(), num));
727 ATH_MSG_DEBUG(std::format("makeServer: Calling shared memory tool with port suffix {}", m_streamPortString.value()));
728 const std::string streamPortSuffix = m_streamPortString.value();
729 if (m_outputStreamingTool->makeServer(num, streamPortSuffix).isFailure()) {
730 ATH_MSG_ERROR("makeServer: " << m_outputStreamingTool << " failed");
731 return(StatusCode::FAILURE);
732 }
733 // Disable PersistencySvc per output file mode, for SharedWriter Server
734 m_persSvcPerOutput.setValue(false);
735 return(StatusCode::SUCCESS);
736 }
737 return(StatusCode::RECOVERABLE);
738 }
739 if (m_inputStreamingTool.empty()) {
740 return(StatusCode::RECOVERABLE);
741 }
742 ATH_MSG_DEBUG("makeServer: " << m_inputStreamingTool << " = " << num);
743 return(m_inputStreamingTool->makeServer(num, ""));
744}

◆ readData()

StatusCode AthenaPoolSharedIOCnvSvc::readData ( )
overridevirtual

Read the next data object.

Definition at line 767 of file AthenaPoolSharedIOCnvSvc.cxx.

767 {
768 if (m_inputStreamingTool.empty()) {
769 return(StatusCode::FAILURE);
770 }
771 const char* tokenStr = nullptr;
772 int num = -1;
773 StatusCode sc = m_inputStreamingTool->clearObject(&tokenStr, num);
774 if (sc.isSuccess() && tokenStr != nullptr && strlen(tokenStr) > 0 && num > 0) {
775 ATH_MSG_DEBUG("readData: " << tokenStr << ", for client: " << num);
776 } else {
777 return(sc);
778 }
779 // Read object instance via POOL/ROOT
780 void* instance = nullptr;
781 Token token;
782 token.fromString(tokenStr); tokenStr = nullptr;
783 if (token.classID() != Guid::null()) {
784 std::string objName = "ALL";
785 if (useDetailChronoStat()) {
786 objName = token.classID().toString();
787 }
788 // StopWatch listens from here until the end of this current scope
789 PMonUtils::BasicStopWatch stopWatch("cObj_" + objName, this->m_chronoMap);
790 this->setObjPtr(instance, &token);
791 // Serialize object via ROOT
793 void* buffer = nullptr;
794 std::size_t nbytes = 0;
795 buffer = m_serializeSvc->serialize(instance, cltype, nbytes);
796 sc = m_inputStreamingTool->putObject(buffer, nbytes, num);
797 while (sc.isRecoverable()) {
798 sc = m_inputStreamingTool->putObject(buffer, nbytes, num);
799 }
800 delete [] static_cast<char*>(buffer); buffer = nullptr;
801 if (!sc.isSuccess()) {
802 ATH_MSG_ERROR("Could not share object for: " << token.toString());
803 return(StatusCode::FAILURE);
804 }
805 const pool::DbTypeInfo* info = pool::DbTypeInfo::create(token.classID());
806 if (info != nullptr) {
807 if (m_auxDynTool->hasAuxStore(token.contID(), info->clazz().Class() ) && !m_auxInput->sendStore(info->clazz().Class(), instance, token.classID().toString(), token.contID(), num).isSuccess()) {
808 ATH_MSG_ERROR("Could not share dynamic aux store for: " << token.toString());
809 return(StatusCode::FAILURE);
810 }
811 }
812 cltype.Destruct(instance); instance = nullptr;
813 if (!m_inputStreamingTool->putObject(nullptr, 0, num).isSuccess()) {
814 ATH_MSG_ERROR("Could not share object for: " << token.toString());
815 return(StatusCode::FAILURE);
816 }
817 } else if (token.dbID() != Guid::null()) {
818 std::string returnToken;
819 Token* metadataToken = getPoolSvc()->getToken("FID:" + token.dbID().toString(), token.contID(), token.oid().first);
820 if( metadataToken ) {
821 returnToken = metadataToken->toString();
822 metadataToken->release(); metadataToken = nullptr;
823 } else {
824 returnToken = token.toString();
825 }
826 // Share token
827 sc = m_inputStreamingTool->putObject(returnToken.c_str(), returnToken.size() + 1, num);
828 if (!sc.isSuccess() || !m_inputStreamingTool->putObject(nullptr, 0, num).isSuccess()) {
829 ATH_MSG_ERROR("Could not share token for: " << token.toString());
830 return(StatusCode::FAILURE);
831 }
832 } else {
833 return(StatusCode::RECOVERABLE);
834 }
835 return(StatusCode::SUCCESS);
836}
std::map< std::string, double > instance
constexpr void toString(std::span< char, StrLen > buf, bool uppercase=true) const noexcept
Automatic conversion to string representation.
const std::string & contID() const
Access container identifier.
Definition Token.h:70
const Guid & classID() const
Access database identifier.
Definition Token.h:74
int release()
Release token: Decrease reference count and eventually delete.
Definition Token.cxx:81
const OID_t & oid() const
Access object identifier.
Definition Token.h:82
Token & fromString(const std::string_view from)
Build from the string representation of a token.
Definition Token.cxx:169
const Guid & dbID() const
Access database identifier.
Definition Token.h:65
static const TypeH forGuid(const Guid &info)
Access classes by Guid.
static const DbTypeInfo * create(const std::string &cl_name)
Create type information using name.

◆ registerForWrite()

Token * AthenaPoolSharedIOCnvSvc::registerForWrite ( Placement * placement,
const void * obj,
const RootType & classDesc )
overridevirtual
Returns
a string token to a Data Object written to Pool
Parameters
placement[IN] pointer to the placement hint
obj[IN] pointer to the Data Object to be written to Pool
classDesc[IN] pointer to the Seal class description for the Data Object.

Definition at line 444 of file AthenaPoolSharedIOCnvSvc.cxx.

444 {
445 if (m_makeStreamingToolClient.value() > 0 && !m_outputStreamingTool.empty() && !m_outputStreamingTool->isServer() && !m_outputStreamingTool->isClient()) {
446 if (!makeClient(m_makeStreamingToolClient.value()).isSuccess()) {
447 ATH_MSG_ERROR("Could not make AthenaPoolSharedIOCnvSvc a Share Client");
448 return(nullptr);
449 }
450 }
451 Token* token = nullptr;
452 if (!m_outputStreamingTool.empty() && m_outputStreamingTool->isClient()
453 && (!m_parallelCompression || placement->containerName().compare(0, m_metadataContainerProp.value().size(), m_metadataContainerProp.value()) == 0)) {
454 // Lock object
455 std::string placementStr = placement->toString();
456 placementStr += "[PNAME=";
457 placementStr += classDesc.Name();
458 placementStr += ']';
459 ATH_MSG_VERBOSE("Requesting write object for: " << placementStr);
460 StatusCode sc = m_outputStreamingTool->lockObject(placementStr.c_str());
461 while (sc.isRecoverable()) {
462 //usleep(100);
463 sc = m_outputStreamingTool->lockObject(placementStr.c_str());
464 }
465 if (!sc.isSuccess()) {
466 ATH_MSG_ERROR("Failed to lock Data for " << placementStr);
467 return(nullptr);
468 }
469 // Serialize object via ROOT
470 const void* buffer = nullptr;
471 std::size_t nbytes = 0;
472 bool own = true;
473 if (classDesc.Name() == "Token") {
474 nbytes = strlen(static_cast<const char*>(obj)) + 1;
475 buffer = obj;
476 own = false;
477 } else if (classDesc.IsFundamental()) {
478 nbytes = classDesc.SizeOf();
479 buffer = obj;
480 own = false;
481 } else {
482 buffer = m_serializeSvc->serialize(obj, classDesc, nbytes);
483 }
484 // Share object
485 sc = m_outputStreamingTool->putObject(buffer, nbytes);
486 while (sc.isRecoverable()) {
487 //usleep(100);
488 sc = m_outputStreamingTool->putObject(buffer, nbytes);
489 }
490 if (own) { delete [] static_cast<const char*>(buffer); }
491 buffer = nullptr;
492 if (!sc.isSuccess()) {
493 ATH_MSG_ERROR("Could not share object for: " << placementStr);
494 m_outputStreamingTool->putObject(nullptr, 0).ignore();
495 return(nullptr);
496 }
497 const pool::DbTypeInfo* info = pool::DbTypeInfo::create(pool::DbReflex::guid(classDesc));
498 if (info != nullptr) {
499 if (m_auxDynTool->hasAuxStore(placement->containerName(), info->clazz().Class() ) && !m_auxOutput->sendStore(info->clazz().Class(), obj, pool::DbReflex::guid(classDesc).toString(), placement->containerName()).isSuccess()) {
500 ATH_MSG_ERROR("Could not share dynamic aux store for: " << placementStr);
501 m_outputStreamingTool->putObject(nullptr, 0).ignore();
502 return(nullptr);
503 }
504 }
505 if (!m_outputStreamingTool->putObject(nullptr, 0).isSuccess()) {
506 ATH_MSG_ERROR("Failed to put Data for " << placementStr);
507 return(nullptr);
508 }
509 // Get Token back from Server
510 const char* tokenStr = nullptr;
511 int num = -1;
512 sc = m_outputStreamingTool->clearObject(&tokenStr, num);
513 while (sc.isRecoverable()) {
514 //usleep(100);
515 sc = m_outputStreamingTool->clearObject(&tokenStr, num);
516 }
517 if (!sc.isSuccess()) {
518 ATH_MSG_ERROR("Failed to get Token");
519 return(nullptr);
520 }
521 if (!strcmp(tokenStr, "ABORT")) {
522 ATH_MSG_ERROR("Writer requested ABORT");
523 // tell the server we are leaving
524 m_outputStreamingTool->stop().ignore();
525 return nullptr;
526 }
527 Token* tempToken = new Token();
528 tempToken->fromString(tokenStr); tokenStr = nullptr;
529 tempToken->setClassID(pool::DbReflex::guid(classDesc));
530 token = tempToken; tempToken = nullptr;
531// Client Write Request
532 } else {
533 if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient() && !m_outputStreamingTool->isServer()) {
534 ATH_MSG_DEBUG("registerForWrite SKIPPED for uninitialized server, Placement = " << placement->toString());
535 Token* tempToken = new Token();
536 tempToken->setClassID(pool::DbReflex::guid(classDesc));
537 token = tempToken; tempToken = nullptr;
538 } else if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient() && !m_streamServerActive) {
539 if(placement->technology() == 0) { // No technology specified, use the default
540 placement->setTechnology(pool::DbType::getType(m_defaultContainerType).type());
541 }
542 ATH_MSG_DEBUG("Requested write object for: " << placement->toString());
543 token = getPoolSvc()->registerForWrite(placement, obj, classDesc);
544 } else {
546 placement->setFileName(placement->fileName() + m_streamPortString.value());
547 }
548 token = AthenaPoolCnvSvc::registerForWrite(placement, obj, classDesc);
549 }
550 }
551 return(token);
552}
#define ATH_MSG_VERBOSE(x)
virtual Token * registerForWrite(Placement *placement, const void *obj, const RootType &classDesc) override
const std::string & containerName() const
Access container name.
Definition Placement.h:33
Placement & setFileName(const std::string &fileName)
Set file name.
Definition Placement.h:31
const std::string toString() const
Retrieve the string representation of the placement.
Definition Placement.cxx:15
Placement & setTechnology(int technology)
Set technology type.
Definition Placement.h:39
const std::string & fileName() const
Access file name.
Definition Placement.h:29
int technology() const
Access technology type.
Definition Placement.h:37
std::string Name(unsigned int mod=Reflex::SCOPED) const
Definition RootType.cxx:612
size_t SizeOf() const
Definition RootType.cxx:765
Token & setClassID(const Guid &cl_id)
Access database identifier.
Definition Token.h:76
static Guid guid(const TypeH &id)
Determine Guid (normalized string form) from reflection type.
static DbType getType(const std::string &name)
Access known storage type object by name.

◆ setObjPtr()

void AthenaPoolSharedIOCnvSvc::setObjPtr ( void *& obj,
const Token * token )
overridevirtual
Parameters
obj[OUT] pointer to the Data Object.
token[IN] string token of the Data Object for which a Pool Ref is filled.

Definition at line 554 of file AthenaPoolSharedIOCnvSvc.cxx.

554 {
555 if (m_makeStreamingToolClient.value() > 0 && !m_inputStreamingTool.empty() && !m_inputStreamingTool->isServer() && !m_inputStreamingTool->isClient()) {
556 if (!makeClient(-m_makeStreamingToolClient.value()).isSuccess()) {
557 ATH_MSG_ERROR("Could not make AthenaPoolSharedIOCnvSvc a Share Client");
558 }
559 }
560 if (!m_outputStreamingTool.empty() && m_outputStreamingTool->isServer()) {
561 if (token->dbID() == Guid::null()) {
562 int num = token->oid().first;
563 // Get object from SHM
564 void* buffer = nullptr;
565 std::size_t nbytes = 0;
566 StatusCode sc = m_outputStreamingTool->getObject(&buffer, nbytes, num);
567 while (sc.isRecoverable()) {
568 sc = m_outputStreamingTool->getObject(&buffer, nbytes, num);
569 }
570 if (!sc.isSuccess()) {
571 ATH_MSG_ERROR("Failed to get Data for " << token->toString());
572 obj = nullptr;
573 } else {
574 ATH_MSG_DEBUG("Server deserializing " << token->toString());
575 if (token->classID() != Guid::null()) {
576 // Deserialize object
577 RootType cltype(pool::DbReflex::forGuid(token->classID()));
578 obj = m_serializeSvc->deserialize(buffer, nbytes, cltype); buffer = nullptr;
579 } else {
580 // Deserialize object
581 std::string className = token->auxString();
582 className = className.substr(className.find("[PNAME="));
583 className = className.substr(7, className.find(']') - 7);
584 RootType cltype(RootType::ByNameNoQuiet(className));
585 obj = m_serializeSvc->deserialize(buffer, nbytes, cltype); buffer = nullptr;
586 }
587 buffer = nullptr;
588 nbytes = 0;
589 sc = m_outputStreamingTool->getObject(&buffer, nbytes, num);
590 while (sc.isRecoverable() && nbytes > 0) {
591 sc = m_outputStreamingTool->getObject(&buffer, nbytes, num);
592 }
593 if (sc.isSuccess() && nbytes > 0) { // Found dynamic attributes
594 Guid classId;
595 classId.fromString(static_cast<const char*>(buffer));
596 if (m_outputStreamingTool->getObject(&buffer, nbytes, num).isSuccess() && nbytes > 0) {
597 const std::string contName = std::string(static_cast<const char*>(buffer));
598 if (classId != Guid::null()) {
599 const pool::DbTypeInfo* info = pool::DbTypeInfo::create(classId);
600 if (info != nullptr) {
601 if (m_auxDynTool->hasAuxStore(contName, info->clazz().Class() ) && !m_auxOutput->receiveStore(info->clazz().Class(), obj, num).isSuccess()) {
602 ATH_MSG_ERROR("Failed to get Dynamic Aux Store for " << token->toString());
603 obj = nullptr;
604 }
605 }
606 }
607 }
608 }
609 }
610 }
611 }
612 if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient() && (m_streamingTechnology.value() < 0 || token->technology() == m_streamingTechnology.value())) {
613 ATH_MSG_VERBOSE("Requesting remote object for: " << token->toString());
614 if (!m_inputStreamingTool->lockObject(token->toString().c_str()).isSuccess()) {
615 ATH_MSG_ERROR("Failed to lock Data for " << token->toString());
616 obj = nullptr;
617 } else {
618 void* buffer = nullptr;
619 std::size_t nbytes = 0;
620 StatusCode sc = StatusCode::FAILURE;
621 // StopWatch listens from here until the end of this current scope
622 {
623 PMonUtils::BasicStopWatch stopWatch("gObj_ALL", this->m_chronoMap);
624 sc = m_inputStreamingTool->getObject(&buffer, nbytes);
625 while (sc.isRecoverable()) {
626 // sleep
627 sc = m_inputStreamingTool->getObject(&buffer, nbytes);
628 }
629 }
630 if (!sc.isSuccess()) {
631 ATH_MSG_ERROR("Failed to get Data for " << token->toString());
632 obj = nullptr;
633 } else {
634 obj = m_serializeSvc->deserialize(buffer, nbytes, token->classID()); buffer = nullptr;
635 buffer = nullptr;
636 nbytes = 0;
637 sc = m_inputStreamingTool->getObject(&buffer, nbytes);
638 while (sc.isRecoverable() && nbytes > 0) {
639 sc = m_inputStreamingTool->getObject(&buffer, nbytes);
640 }
641 if (sc.isSuccess() && nbytes > 0) { // Found dynamic attributes
642 Guid classId;
643 classId.fromString(static_cast<const char*>(buffer));
644 if (m_inputStreamingTool->getObject(&buffer, nbytes).isSuccess() && nbytes > 0) {
645 const std::string contName = std::string(static_cast<const char*>(buffer));
646 if (classId != Guid::null()) {
647 const pool::DbTypeInfo* info = pool::DbTypeInfo::create(classId);
648 if (info != nullptr) {
649 if (!m_auxInput->receiveStore(info->clazz().Class(), obj).isSuccess()) {
650 ATH_MSG_ERROR("Failed to get Dynamic Aux Store for " << token->toString());
651 obj = nullptr;
652 }
653 }
654 }
655 }
656 }
657 }
658 }
659 } else if (token->dbID() != Guid::null()) {
660 AthenaPoolCnvSvc::setObjPtr(obj, token);
661 }
662}
virtual void setObjPtr(void *&obj, const Token *token) override
Gaudi::Property< int > m_streamingTechnology
Use Streaming for selected technologies only.
constexpr void fromString(std::string_view s)
Automatic conversion from string representation.
Definition Guid.h:143
const std::string & auxString() const
Access auxiliary string.
Definition Token.h:92
int technology() const
Access technology type.
Definition Token.h:78

◆ SvcFactory< AthenaPoolSharedIOCnvSvc >

friend class SvcFactory< AthenaPoolSharedIOCnvSvc >
friend

Definition at line 1 of file AthenaPoolSharedIOCnvSvc.h.

Member Data Documentation

◆ m_auxDynTool

std::unique_ptr<RootAuxDynIO::IFactoryTool> AthenaPoolSharedIOCnvSvc::m_auxDynTool
private

Definition at line 121 of file AthenaPoolSharedIOCnvSvc.h.

◆ m_auxInput

std::unique_ptr<RootAuxDynIO::IAuxDynShare> AthenaPoolSharedIOCnvSvc::m_auxInput
private

Definition at line 123 of file AthenaPoolSharedIOCnvSvc.h.

◆ m_auxOutput

std::unique_ptr<RootAuxDynIO::IAuxDynShare> AthenaPoolSharedIOCnvSvc::m_auxOutput
private

Definition at line 125 of file AthenaPoolSharedIOCnvSvc.h.

◆ m_fileCommitCounter

std::map<std::string, int> AthenaPoolSharedIOCnvSvc::m_fileCommitCounter
private

Force SharedWriter to flush data to output file at given intervals, needed by parallel compression.

Definition at line 145 of file AthenaPoolSharedIOCnvSvc.h.

◆ m_fileFlushSetting

Gaudi::Property<std::map<std::string, int> > AthenaPoolSharedIOCnvSvc::m_fileFlushSetting {this,"FileFlushSetting",{}}
private

Definition at line 146 of file AthenaPoolSharedIOCnvSvc.h.

146{this,"FileFlushSetting",{}};

◆ m_inputStreamingTool

ToolHandle<IAthenaIPCTool> AthenaPoolSharedIOCnvSvc::m_inputStreamingTool {this,"InputStreamingTool",{}}
private

Definition at line 122 of file AthenaPoolSharedIOCnvSvc.h.

122{this,"InputStreamingTool",{}};

◆ m_makeStreamingToolClient

Gaudi::Property<int> AthenaPoolSharedIOCnvSvc::m_makeStreamingToolClient {this,"MakeStreamingToolClient",0}
private

Make this instance a Streaming Client during first connect/write automatically.

Definition at line 137 of file AthenaPoolSharedIOCnvSvc.h.

137{this,"MakeStreamingToolClient",0};

◆ m_metadataClient

int AthenaPoolSharedIOCnvSvc::m_metadataClient =0
private

Definition at line 128 of file AthenaPoolSharedIOCnvSvc.h.

◆ m_metadataContainerProp

Gaudi::Property<std::string> AthenaPoolSharedIOCnvSvc::m_metadataContainerProp {this,"OutputMetadataContainer","MetaData"}
private

For SharedWriter: To use MetadataSvc to merge data placed in a certain container.

Definition at line 133 of file AthenaPoolSharedIOCnvSvc.h.

133{this,"OutputMetadataContainer","MetaData"};

◆ m_metadataContainersAug

Gaudi::Property<std::vector<std::string> > AthenaPoolSharedIOCnvSvc::m_metadataContainersAug {this, "OutputMetadataContainers", {}, "Metadata containers used for augmentations"}
private

Definition at line 134 of file AthenaPoolSharedIOCnvSvc.h.

134{this, "OutputMetadataContainers", {}, "Metadata containers used for augmentations"};

◆ m_outputStreamingTool

ToolHandle<IAthenaIPCTool> AthenaPoolSharedIOCnvSvc::m_outputStreamingTool {this,"OutputStreamingTool",{}}
private

Definition at line 124 of file AthenaPoolSharedIOCnvSvc.h.

124{this,"OutputStreamingTool",{}};

◆ m_parallelCompression

Gaudi::Property<bool> AthenaPoolSharedIOCnvSvc::m_parallelCompression {this,"ParallelCompression",true}
private

Use Athena Object sharing for metadata only, event data is collected and send via ROOT TMemFile.

Definition at line 141 of file AthenaPoolSharedIOCnvSvc.h.

141{this,"ParallelCompression",true};

◆ m_serializeSvc

ServiceHandle<IAthenaSerializeSvc> AthenaPoolSharedIOCnvSvc::m_serializeSvc {this,"AthenaRootSerializeSvc","AthenaRootSerializeSvc"}
private

Definition at line 120 of file AthenaPoolSharedIOCnvSvc.h.

120{this,"AthenaRootSerializeSvc","AthenaRootSerializeSvc"};

◆ m_streamingTechnology

Gaudi::Property<int> AthenaPoolSharedIOCnvSvc::m_streamingTechnology {this,"StreamingTechnology",-1}
private

Use Streaming for selected technologies only.

Definition at line 139 of file AthenaPoolSharedIOCnvSvc.h.

139{this,"StreamingTechnology",-1};

◆ m_streamPortString

Gaudi::Property<std::string> AthenaPoolSharedIOCnvSvc::m_streamPortString {this,"StreamPortString","?pmerge=localhost:0"}
private

Extension to use ROOT TMemFile for event data, "?pmerge=<host>:<port>".

Definition at line 143 of file AthenaPoolSharedIOCnvSvc.h.

143{this,"StreamPortString","?pmerge=localhost:0"};

◆ m_streamServerActive

bool AthenaPoolSharedIOCnvSvc::m_streamServerActive =false
private

Definition at line 127 of file AthenaPoolSharedIOCnvSvc.h.


The documentation for this class was generated from the following files: