3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
10 //* Permission to use, copy, modify and distribute this software and its *
11 //* documentation strictly for non-commercial purposes is hereby granted *
12 //* without fee, provided that the above copyright notice appears in all *
13 //* copies and that both the copyright notice and this permission notice *
14 //* appear in the supporting documentation. The authors make no claims *
15 //* about the suitability of this software for any purpose. It is *
16 //* provided "as is" without express or implied warranty. *
17 //**************************************************************************
19 /** @file AliHLTDumpTask.cxx
20 @author Matthias Richter
22 @brief Base class for data sinks with direct buffer access.
25 #include "AliHLTDumpTask.h"
27 /** ROOT macro for the implementation of ROOT specific class methods */
28 ClassImp(AliHLTDumpTask)
30 AliHLTDumpTask::AliHLTDumpTask(const char* chains)
34 fpDummyConfiguration(NULL),
37 // see header file for class documentation
39 // refer to README to build package
41 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
42 if (chains && chains[0]!=0) SetChains(chains);
45 AliHLTDumpTask::~AliHLTDumpTask()
47 // see header file for class documentation
49 // UnsetTarget called automatically
50 if (fpDummyTask) delete fpDummyTask;
53 if (fpDummyConfiguration) delete fpDummyConfiguration;
54 fpDummyConfiguration=NULL;
56 if (fpConfiguration) delete fpConfiguration;
60 int AliHLTDumpTask::SetChains(const char* chains)
62 // see header file for class documentation
63 if (!chains || chains[0]==0) {
64 HLTError("invalid chain id string");
67 TString taskname=chains;
68 taskname.ReplaceAll(" ", "_");
69 taskname+="_hltDumpTask";
71 // This is just a trick to use the existing Task handling, especially the
72 // ProcessTask function.
73 // 1. The 'BlockFilter' just forwards the data blocks of all specified chains
74 // 2. A dummy task is added to the target list in order to set the data segments
75 // after forwarding. In case of an empty target list the data is just discarded.
76 // That's maybe not the most elegant solution but far less awkward as one would
78 fpConfiguration=new AliHLTConfiguration(taskname.Data(), "BlockFilter", chains, NULL);
79 TString dummyname=chains;
80 dummyname.ReplaceAll(" ", "_");
81 dummyname+="_never_used_dummy_";
82 fpDummyConfiguration=new AliHLTConfiguration(dummyname.Data(), "BlockFilter", taskname.Data(), NULL);
83 if (fpDummyConfiguration) {
84 fpDummyTask=new AliHLTTask(fpDummyConfiguration);
85 SetTarget(fpDummyTask);
90 int AliHLTDumpTask::CustomInit(AliHLTComponentHandler* pCH)
92 // see header file for class documentation
93 if (!fpDummyTask) return -ENOENT;
94 return fpDummyTask->Init(NULL, pCH);
97 int AliHLTDumpTask::CustomCleanup()
99 // see header file for class documentation
100 if (!fpDummyTask) return -ENOENT;
101 return fpDummyTask->Deinit();
104 const char* AliHLTDumpTask::GetSourceChains() const
106 // see header file for class documentation
107 if (!fpConfiguration) return "";
108 return fpConfiguration->GetSourceSettings();
111 const AliHLTComponentBlockDataList& AliHLTDumpTask::GetDataBlocks()
113 // see header file for class documentation
114 if (fBlocks.size()>0) return fBlocks;
116 if (!fpDataBuffer->FindConsumer(fpDummyTask->GetComponent())) {
117 // in order to subscribe to the buffers the dummy consumer
118 // needs to be set. The dummy task is not in the AliHLTSystem chain
119 // and therefor not automatically set.
120 fpDataBuffer->SetConsumer(fpDummyTask->GetComponent());
123 if (fpDataBuffer->GetNofSegments()>0
124 && fpDataBuffer->FindConsumer(fpDummyTask->GetComponent(), 0 /*search only among pending consumers*/)>0) {
125 if (fpDataBuffer->Subscribe(fpDummyTask->GetComponent(), fBlocks)>=0) {
128 HLTError("failed to subscribe to data buffer");
132 // 2008-08-07 this is not a failure condition
133 // If the chain has not been processed because LocalReconstruction
134 // is not enabled, the task will be empty
135 //HLTWarning("no data buffer available");
141 int AliHLTDumpTask::ReleaseDataBlocks()
143 // see header file for class documentation
145 if (!fpDataBuffer) return 0;
147 if (fBlocks.size()==0 && fpDataBuffer->GetNofPendingConsumers()>0) {
148 // There are data blocks in the parents which this task has not yet
149 // subscribed to. The subscription takes place in GetDataBlocks.
150 // However, this method is not necessarily called.
152 // In order to switch buffer states correctly, first let the dummy
153 // task as the only consumer subscribe to all those buffers and
154 // release them further down. Basically, the buffers are arranged
155 // in a different internal list, which is the only state they can be
156 // released from. This approach has been chosen to implement the
157 // DumpTask having no real consumers but at the same time has to
158 // behave like a normal task in AliHLTTask::ProcessTask
159 fpDataBuffer->Subscribe(fpDummyTask->GetComponent(), fBlocks);
162 for (unsigned int i=0; i<fBlocks.size(); i++) {
163 fpDataBuffer->Release(&(fBlocks[i]), fpDummyTask->GetComponent(), this);