]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDataBuffer.cxx
bugfix AliHLTDataBuffer: correct handling of pointer and offset in block descriptor...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataBuffer.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
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  **************************************************************************/
18
19 /** @file   AliHLTDataBuffer.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Handling of Data Buffers for HLT components.
23 */
24
25 // see header file for class documentation
26 // or
27 // refer to README to build package
28 // or
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31 #if __GNUC__>= 3
32 using namespace std;
33 #endif
34
35 #include "AliHLTDataBuffer.h"
36 #include "AliHLTConsumerDescriptor.h"
37 #include "AliHLTComponent.h"
38 #include <cerrno>
39 //#include <string>
40 //#include "AliHLTSystem.h"
41
42 /** ROOT macro for the implementation of ROOT specific class methods */
43 ClassImp(AliHLTDataBuffer)
44
45 AliHLTDataBuffer::AliHLTDataBuffer()
46   :
47   fSegments(),
48   fConsumers(),
49   fActiveConsumers(),
50   fReleasedConsumers(),
51   fpBuffer(NULL),
52   fFlags(0)
53 {
54   // see header file for class documentation
55   // or
56   // refer to README to build package
57   // or
58   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
59   fSegments.empty();
60   fConsumers.empty();
61   fActiveConsumers.empty();
62   fReleasedConsumers.empty();
63   fgNofInstances++;
64 }
65
66 int AliHLTDataBuffer::fgNofInstances=0;
67 vector<AliHLTDataBuffer::AliHLTRawBuffer*> AliHLTDataBuffer::fgFreeBuffers;
68 vector<AliHLTDataBuffer::AliHLTRawBuffer*> AliHLTDataBuffer::fgActiveBuffers;
69 AliHLTUInt32_t AliHLTDataBuffer::fgMargin=1024;
70 AliHLTLogging AliHLTDataBuffer::fgLogging;
71 const Int_t AliHLTDataBuffer::fgkSafetyPatternSize=16;
72 const char AliHLTDataBuffer::fgkSafetyPattern[]={0x28, 0x63, 0x29, 0x4d, 0x52, 0x49, 0x43, 0x48, 0x54, 0x45, 0x52, 0x20, 0x32, 0x30, 0x30, 0x37};
73
74 AliHLTDataBuffer::~AliHLTDataBuffer()
75 {
76   // see header file for function documentation
77   if (--fgNofInstances<=0) {
78     DeleteRawBuffers();
79   }
80   CleanupConsumerList();
81 }
82
83 int AliHLTDataBuffer::SetConsumer(AliHLTComponent* pConsumer)
84 {
85   // see header file for function documentation
86   int iResult=0;
87   if (pConsumer) {
88     if (FindConsumer(pConsumer)) {
89       HLTWarning("consumer %s (%p) already set to data buffer %p", pConsumer->GetComponentID(), pConsumer, this);
90     }
91     AliHLTConsumerDescriptor* pDesc=new AliHLTConsumerDescriptor(pConsumer);
92     if (pDesc) {
93       fConsumers.push_back(pDesc);
94       HLTDebug("set consumer %s (%p) to data buffer %p", pConsumer->GetComponentID(), pConsumer, this);
95     } else {
96       HLTError("memory allocation failed");
97       iResult=-ENOMEM;
98     }
99   } else {
100     HLTError("invalid parameter: consumer component (nil)");
101     iResult=-EINVAL;
102   }
103   return iResult;
104 }
105
106 int AliHLTDataBuffer::FindMatchingDataBlocks(const AliHLTComponent* pConsumer, vector<AliHLTComponentDataType>* tgtList)
107 {
108   // see header file for function documentation
109   int iResult=0;
110   if (pConsumer) {
111     vector<AliHLTDataBuffer::AliHLTDataSegment> segments;
112     if ((iResult=FindMatchingDataSegments(pConsumer, segments))>=0) {
113       if (tgtList) {
114         vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=segments.begin();
115         while (segment!=segments.end()) {
116           tgtList->push_back((*segment).fDataType);
117           segment++;
118         }
119       }
120       iResult=segments.size();
121     }
122   } else {
123     iResult=-EINVAL;
124   }
125   return iResult;
126 }
127
128 int AliHLTDataBuffer::FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataBuffer::AliHLTDataSegment>& tgtList)
129 {
130   // see header file for function documentation
131   int iResult=0;
132
133   // Matthias 26.09.2007 relax the restriction to matching data blocks
134   // all blocks are passed to the consumer, which is the policy also in
135   // PubSub
136   tgtList.assign(fSegments.begin(), fSegments.end());
137   iResult=tgtList.size();
138   return iResult;
139   
140   if (pConsumer) {
141     vector<AliHLTComponentDataType> dtlist;
142     ((AliHLTComponent*)pConsumer)->GetInputDataTypes(dtlist);
143     vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=fSegments.begin();
144     while (segment!=fSegments.end()) {
145       vector<AliHLTComponentDataType>::iterator type=dtlist.begin();
146       while (type!=dtlist.end()) {
147         if ((*segment).fDataType==(*type) ||
148             (*type)==kAliHLTAnyDataType) {
149           tgtList.push_back(*segment);
150           iResult++;
151           break;
152         }
153         type++;
154       }
155       segment++;
156     }
157   } else {
158     iResult=-EINVAL;
159   }
160   return iResult;
161 }
162
163 int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponentBlockData* arrayBlockDesc, int iArraySize)
164 {
165   // see header file for function documentation
166   int iResult=0;
167   if (pConsumer && arrayBlockDesc) {
168     if (fpBuffer) {
169       AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fConsumers);
170       if (pDesc) {
171         vector<AliHLTDataBuffer::AliHLTDataSegment> tgtList;
172         // Matthias 26.07.2007 AliHLTSystem should behave the same way as PubSub
173         // so it does not matter if there are matching data types or not, unless
174         // we implement such a check in PubSub
175         if ((iResult=FindMatchingDataSegments(pConsumer, tgtList))>=0) {
176           int i =0;
177           vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=tgtList.begin();
178           while (segment!=tgtList.end() && i<iArraySize) {
179             // fill the block data descriptor
180             arrayBlockDesc[i].fStructSize=sizeof(AliHLTComponentBlockData);
181             // the shared memory key is not used in AliRoot
182             arrayBlockDesc[i].fShmKey.fStructSize=sizeof(AliHLTComponentShmData);
183             arrayBlockDesc[i].fShmKey.fShmType=gkAliHLTComponentInvalidShmType;
184             arrayBlockDesc[i].fShmKey.fShmID=gkAliHLTComponentInvalidShmID;
185             // This models the behavior of PubSub.
186             // For incoming data blocks, fOffset must be ignored by the
187             // processing component. It is set for bookkeeping in the framework.
188             // fPtr always points to the beginning of the data.
189             arrayBlockDesc[i].fOffset=(*segment).fSegmentOffset;
190             AliHLTUInt8_t* pTgt=*fpBuffer;
191             pTgt+=(*segment).fSegmentOffset;
192             arrayBlockDesc[i].fPtr=reinterpret_cast<void*>(pTgt);
193             arrayBlockDesc[i].fSize=(*segment).fSegmentSize;
194             arrayBlockDesc[i].fDataType=(*segment).fDataType;
195             arrayBlockDesc[i].fSpecification=(*segment).fSpecification;
196             pDesc->SetActiveDataSegment(arrayBlockDesc[i].fOffset, arrayBlockDesc[i].fSize);
197             HLTDebug("component %p (%s) subscribed to segment #%d offset %d size %d data type %s %#x", 
198                      pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), i, arrayBlockDesc[i].fOffset,
199                      arrayBlockDesc[i].fSize, (AliHLTComponent::DataType2Text(arrayBlockDesc[i].fDataType)).c_str(), 
200                      arrayBlockDesc[i].fSpecification);
201             i++;
202             segment++;
203           }
204           // check whether there was enough space for the segments
205           if (i!=(int)tgtList.size()) {
206             HLTError("too little space in block descriptor array: required %d, available %d", tgtList.size(), iArraySize);
207             iResult=-ENOSPC;
208           } else {
209           // move this consumer to the active list
210           if (ChangeConsumerState(pDesc, fConsumers, fActiveConsumers)>=0) {
211             HLTDebug("component %p (%s) subscribed to data buffer %p", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this);
212           } else {
213             // TODO: cleanup the consumer descriptor correctly
214             memset(arrayBlockDesc, 0, iArraySize*sizeof(AliHLTComponentBlockData));
215             HLTError("can not activate consumer %p for data buffer %p", pConsumer, this);
216             iResult=-EACCES;
217           }
218           }
219         } else {
220           HLTError("unresolved data segment(s) for component %p (%s)", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID());
221           iResult=-EBADF;
222         }
223       } else {
224         HLTError("component %p is not a data consumer of data buffer %s", pConsumer, this);
225         iResult=-ENOENT;
226       }
227     } else {
228       // Matthias 26.07.2007 until now, data had to be present for successful subscription
229       // in order to be consistent with the PubSub framework, this restiction has been
230       // removed
231       //HLTError("data buffer %p is empty", this);
232       //iResult=-ENODATA;
233     }
234   } else {
235     HLTError("invalid parameter");
236     iResult=-EINVAL;
237   }
238   return iResult;
239 }
240
241 int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer)
242 {
243   // see header file for function documentation
244   int iResult=0;
245   if (pBlockDesc && pConsumer) {
246     AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fActiveConsumers);
247     if (pDesc) {
248       if ((iResult=pDesc->CheckActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize))!=1) {
249         HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize);
250         // TODO: appropriate error handling, but so far optional
251         iResult=0;
252       } else {
253         pDesc->ReleaseActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize);
254         pBlockDesc->fOffset=0;
255         pBlockDesc->fPtr=NULL;
256         pBlockDesc->fSize=0;
257       }
258       if (pDesc->GetNofActiveSegments()==0) {
259         if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
260           if (GetNofActiveConsumers()==0 && GetNofPendingConsumers()==0) {
261             // this is the last consumer, reset the consumer list and release the raw buffer
262             ResetDataBuffer();
263           }
264         } else {
265           HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
266           iResult=-EACCES;
267         }
268       }
269     } else {
270       HLTWarning("component %p has currently not subscribed to the data buffer %p", pConsumer, this);
271       iResult=-ENOENT;
272     }
273   } else {
274     HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
275     iResult=-EINVAL;
276   }
277   return iResult;
278 }
279
280 AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize)
281 {
282   // see header file for function documentation
283   AliHLTUInt8_t* pTargetBuffer=NULL;
284   if (fpBuffer!=NULL) {
285     HLTWarning("data buffer not properly reset, possible memory leak\n");
286   }
287   fpBuffer=CreateRawBuffer(iMinSize);
288   if (fpBuffer) {
289     pTargetBuffer=*fpBuffer;
290   } else {
291     HLTError("can not create raw buffer");
292   }
293   return pTargetBuffer;
294 }
295
296 int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arrayBlockData, int iSize)
297 {
298   // see header file for function documentation
299   int iResult=0;
300   if (pTgt && arrayBlockData && iSize>=0) {
301     if (fpBuffer) {
302       if (*fpBuffer==pTgt) {
303         AliHLTDataBuffer::AliHLTDataSegment segment;
304         for (int i=0; i<iSize; i++) {
305           // This function has to model the behavior of PubSub
306           // For output blocks only the fOffset value is used, this must be the offset
307           // relative to the output pointer. fPtr must be either NULL or the output
308           // pointer
309           if (arrayBlockData[i].fPtr==NULL ||
310               arrayBlockData[i].fPtr==*fpBuffer) {
311             if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<=fpBuffer->fSize) {
312               segment.fSegmentOffset=arrayBlockData[i].fOffset;
313               segment.fSegmentSize=arrayBlockData[i].fSize;
314               segment.fDataType=arrayBlockData[i].fDataType;
315               segment.fSpecification=arrayBlockData[i].fSpecification;
316               fSegments.push_back(segment);
317               HLTDebug("set segment %s with size %d at offset %d", AliHLTComponent::DataType2Text(segment.fDataType).data(), segment.fSegmentSize, segment.fSegmentOffset);
318             } else {
319               HLTError("block data specification %#d (%s) exceeds size of data buffer", i, AliHLTComponent::DataType2Text(arrayBlockData[i].fDataType).data());
320               HLTError("block offset=%d, block size=%d, buffer size=%d", arrayBlockData[i].fOffset, arrayBlockData[i].fSize, fpBuffer->fSize);
321               iResult=-E2BIG;
322             }
323           } else {
324             HLTError("invalid pointer (%p) in block data specification (buffer %p size %d)."
325                      "please note: for output blocks only the fOffset value is valid and must "
326                      "be relative to the output buffer", arrayBlockData[i].fPtr, fpBuffer->fPtr, fpBuffer->fSize);
327             iResult=-ERANGE;
328           }
329         }
330       } else {
331         HLTError("this data buffer (%p) does not match the internal data buffer %p of raw buffer %p", pTgt, fpBuffer->fPtr, fpBuffer);
332         iResult=-EINVAL;
333       }
334     } else {
335       HLTFatal("internal data structur missmatch");
336       iResult=-EFAULT;
337     }
338   } else {
339     HLTError("invalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData);
340     iResult=-EINVAL;
341   }
342   return iResult;
343 }
344
345 int AliHLTDataBuffer::IsEmpty()
346 {
347   // see header file for function documentation
348   int iResult=fpBuffer==NULL || GetNofSegments()==0;
349   return iResult;
350 }
351
352 int AliHLTDataBuffer::GetNofSegments()
353 {
354   // see header file for function documentation
355   int iResult=fSegments.size();
356   return iResult;
357 }
358
359 int AliHLTDataBuffer::GetNofConsumers()
360 {
361   // see header file for function documentation
362   int iResult=fConsumers.size() + GetNofActiveConsumers() + fReleasedConsumers.size();
363   return iResult;
364 }
365
366 int AliHLTDataBuffer::GetNofPendingConsumers()
367 {
368   // see header file for function documentation
369   int iResult=fConsumers.size();
370   return iResult;
371 }
372
373 int AliHLTDataBuffer::GetNofActiveConsumers()
374 {
375   // see header file for function documentation
376   int iResult=fActiveConsumers.size();
377   return iResult;
378 }
379
380 AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::CreateRawBuffer(AliHLTUInt32_t size)
381 {
382   // see header file for function documentation
383   AliHLTRawBuffer* pRawBuffer=NULL;
384   unsigned int reqSize=size+fgkSafetyPatternSize;
385   vector<AliHLTRawBuffer*>::iterator buffer=fgFreeBuffers.begin();
386   while (buffer!=fgFreeBuffers.end() && pRawBuffer==NULL) {
387     if ((*buffer)->fTotalSize>=reqSize && ((*buffer)->fTotalSize-reqSize)<fgMargin) {
388       // assign this element
389       pRawBuffer=*buffer;
390       pRawBuffer->fSize=size;
391       fgFreeBuffers.erase(buffer);
392       fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "raw buffer container %p provided for request of %d bytes (total %d available in buffer %p)", pRawBuffer, size, pRawBuffer->fTotalSize, pRawBuffer->fPtr);
393       fgActiveBuffers.push_back(pRawBuffer);
394       break;
395     }
396     buffer++;
397   }
398   if (pRawBuffer==NULL) {
399     // no buffer found, create a new one
400     pRawBuffer=new AliHLTRawBuffer;
401     if (pRawBuffer) {
402       pRawBuffer->fPtr=static_cast<AliHLTUInt8_t*>(malloc(reqSize));
403       if (pRawBuffer->fPtr) {
404         pRawBuffer->fSize=size;
405         pRawBuffer->fTotalSize=reqSize;
406         fgActiveBuffers.push_back(pRawBuffer);
407         fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "new raw buffer %p of size %d created (container %p)", pRawBuffer->fPtr, pRawBuffer->fTotalSize, pRawBuffer);
408       } else {
409         delete pRawBuffer;
410         pRawBuffer=NULL;
411         fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed");
412       } 
413     } else {
414       fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed");
415     }
416   }
417   if (pRawBuffer!=NULL && fgkSafetyPatternSize>0) {
418     //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "writing safety pattern to %p offset %d", pRawBuffer->fPtr, pRawBuffer->fSize);
419     memcpy(((char*)pRawBuffer->fPtr)+pRawBuffer->fSize, fgkSafetyPattern, fgkSafetyPatternSize);
420   }
421   return pRawBuffer;
422 }
423
424 int AliHLTDataBuffer::ReleaseRawBuffer(AliHLTRawBuffer* pBuffer)
425 {
426   // see header file for function documentation
427   int iResult=0;
428   if (pBuffer) {
429     vector<AliHLTRawBuffer*>::iterator buffer=fgActiveBuffers.begin();
430     while (buffer!=fgActiveBuffers.end() && (*buffer)!=pBuffer) {
431       buffer++;
432     }
433     if (buffer!=fgActiveBuffers.end()) {
434       if (fgkSafetyPatternSize>0) {
435         //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "comparing safety pattern at %p offset %d", (*buffer)->fPtr, (*buffer)->fSize);
436         if (memcmp(((char*)(*buffer)->fPtr)+(*buffer)->fSize, fgkSafetyPattern, fgkSafetyPatternSize)!=0) {
437           fgLogging.Logging(kHLTLogFatal, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "component has written beyond end of data buffer %p size %d", (*buffer)->fPtr, (*buffer)->fSize);
438         }
439       }
440       (*buffer)->fSize=0;
441       fgFreeBuffers.push_back(*buffer);
442       fgActiveBuffers.erase(buffer);
443     } else {
444       fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "can not find raw buffer container %p in the list of active containers", pBuffer);
445       iResult=-ENOENT;
446     }
447   } else {
448     fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "invalid parameter");
449     iResult=-EINVAL;
450   }
451   return iResult;
452 }
453
454
455 int AliHLTDataBuffer::DeleteRawBuffers() 
456 {
457   // see header file for function documentation
458   int iResult=0;
459   vector<AliHLTRawBuffer*>::iterator buffer=fgFreeBuffers.begin();
460   while (buffer!=fgFreeBuffers.end()) {
461     free((*buffer)->fPtr);
462     delete *buffer;
463     fgFreeBuffers.erase(buffer);
464     buffer=fgFreeBuffers.begin();
465   }
466   buffer=fgActiveBuffers.begin();
467   while (buffer!=fgActiveBuffers.end()) {
468     fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "request to delete active raw buffer container (raw buffer %p, size %d)", (*buffer)->fPtr, (*buffer)->fTotalSize);
469     free((*buffer)->fPtr);
470     delete *buffer;
471     fgActiveBuffers.erase(buffer);
472     buffer=fgActiveBuffers.begin();
473   }
474   return iResult;
475 }
476
477 AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, vector<AliHLTConsumerDescriptor*> &list) const
478 {
479   // see header file for function documentation
480   AliHLTConsumerDescriptor* pDesc=NULL;
481   vector<AliHLTConsumerDescriptor*>::iterator desc=list.begin();
482   while (desc!=list.end() && pDesc==NULL) {
483     if ((pConsumer==NULL || (*desc)->GetComponent()==pConsumer)) {
484       pDesc=*desc;
485     }
486     desc++;
487   }
488   return pDesc;
489 }
490
491 int AliHLTDataBuffer::ResetDataBuffer() 
492 {
493   // see header file for function documentation
494   int iResult=0;
495   AliHLTRawBuffer* pBuffer=fpBuffer;
496   fpBuffer=NULL;
497
498   // cleanup consumer states
499   vector<AliHLTConsumerDescriptor*>::iterator desc;
500 //   if (GetNofPendingConsumers()>0) {
501 //     desc=fConsumers.begin();
502 //     while (desc!=fConsumers.end()) {
503 //       AliHLTComponent* pComp=(*desc)->GetComponent();
504 //       HLTError("internal error: consumer %p (%s %p) did not get data from data buffer %p", *desc, pComp?pComp->GetComponentID():"", pComp, this);
505 //       desc++;
506 //     }
507 //   }
508   desc=fReleasedConsumers.begin();
509   while (desc!=fReleasedConsumers.end()) {
510     AliHLTConsumerDescriptor* pDesc=*desc;
511     fReleasedConsumers.erase(desc);
512     desc=fReleasedConsumers.begin();
513     fConsumers.push_back(pDesc);
514   }
515   desc=fActiveConsumers.begin();
516   while (desc!=fActiveConsumers.end()) {
517     AliHLTConsumerDescriptor* pDesc=*desc;
518     HLTWarning("consumer %p was not released", pDesc);
519     fActiveConsumers.erase(desc);
520     desc=fActiveConsumers.begin();
521     fConsumers.push_back(pDesc);
522   }
523
524   // cleanup segments
525   vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=fSegments.begin();
526   while (segment!=fSegments.end()) {
527     fSegments.erase(segment);
528     segment=fSegments.begin();
529   }
530
531   // cleanup raw buffer
532   if (pBuffer) {
533     ReleaseRawBuffer(pBuffer);
534   }
535   return iResult;
536 }
537
538 int AliHLTDataBuffer::Reset()
539 {
540   // see header file for function documentation
541   return ResetDataBuffer();
542 }
543
544 // this is the version which works on lists of components instead of consumer descriptors
545 // int AliHLTDataBuffer::ChangeConsumerState(AliHLTComponent* pConsumer, vector<AliHLTComponent*> &srcList, vector<AliHLTComponent*> &tgtList)
546 // {
547 //   int iResult=0;
548 //   if (pDesc) {
549 //     vector<AliHLTComponent*>::iterator desc=srcList.begin();
550 //     while (desc!=srcList.end()) {
551 //       if ((*desc)==pConsumer) {
552 //      srcList.erase(desc);
553 //      tgtList.push_back(pConsumer);
554 //      break;
555 //       }
556 //      desc++;
557 //     }
558 //     if (desc==srcList.end()) {
559 //       HLTError("can not find consumer component %p in list", pConsumer);
560 //       iResult=-ENOENT;
561 //     }
562 //   } else {
563 //     HLTError("invalid parameter");
564 //     iResult=-EINVAL;
565 //   }
566 //   return iResult;
567 // }
568
569 int AliHLTDataBuffer::ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList)
570 {
571   // see header file for function documentation
572   int iResult=-ENOENT;
573   if (pDesc) {
574     vector<AliHLTConsumerDescriptor*>::iterator desc=srcList.begin();
575     while (desc!=srcList.end()) {
576       if ((*desc)==pDesc) {
577         srcList.erase(desc);
578         tgtList.push_back(pDesc);
579         iResult=0;
580         break;
581       }
582       desc++;
583     }
584     if (iResult<0) {
585       HLTError("can not find consumer descriptor %p in list", pDesc);
586     }
587   } else {
588     HLTError("invalid parameter");
589     iResult=-EINVAL;
590   }
591   return iResult;
592 }
593
594 int AliHLTDataBuffer::CleanupConsumerList() 
595 {
596   // see header file for function documentation
597   int iResult=0;
598   ResetDataBuffer();
599   vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin();
600   while (desc!=fConsumers.end()) {
601     delete *desc;
602     fConsumers.erase(desc);
603     desc=fConsumers.begin();
604   }
605   return iResult;
606 }
607
608 int AliHLTDataBuffer::FindConsumer(AliHLTComponent* pConsumer, int bAllLists)
609 {
610   // see header file for function documentation
611   vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin();
612   while (desc!=fConsumers.end()) {
613     if ((*desc)->GetComponent()==pConsumer)
614       return 1;
615     desc++;
616   }
617   if (bAllLists==0) return 0;
618
619   desc=fActiveConsumers.begin();
620   while (desc!=fActiveConsumers.end()) {
621     if ((*desc)->GetComponent()==pConsumer)
622       return 1;
623     desc++;
624   }
625   desc=fReleasedConsumers.begin();
626   while (desc!=fReleasedConsumers.end()) {
627     if ((*desc)->GetComponent()==pConsumer)
628       return 1;
629     desc++;
630   }
631   return 0;
632 }
633
634 int AliHLTDataBuffer::AliHLTRawBuffer::operator==(void* ptr)
635 {
636   return fPtr == static_cast<AliHLTUInt8_t*>(ptr);
637 }
638
639 int AliHLTDataBuffer::AliHLTRawBuffer::operator<=(void* ptr)
640 {
641   int iResult=fPtr <= static_cast<AliHLTUInt8_t*>(ptr);
642   //printf("%p: %p <= %p (%d)\n", this, fPtr, ptr, iResult);
643   return iResult;
644 }
645
646 int AliHLTDataBuffer::AliHLTRawBuffer::operator>(void* ptr)
647 {
648   int iResult=fPtr+fSize > static_cast<AliHLTUInt8_t*>(ptr);
649   //printf("%p: %p + %d > %p (%d)\n", this, fPtr, fSize, ptr, iResult);
650   return iResult;
651 }
652
653 int AliHLTDataBuffer::AliHLTRawBuffer::operator-(void* ptr)
654 {
655   return static_cast<int>(static_cast<AliHLTUInt8_t*>(ptr)-fPtr);
656 }