]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDataBuffer.cxx
documentation
[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             arrayBlockDesc[i].fOffset=(*segment).fSegmentOffset;
186             arrayBlockDesc[i].fPtr=*fpBuffer;
187             arrayBlockDesc[i].fSize=(*segment).fSegmentSize;
188             arrayBlockDesc[i].fDataType=(*segment).fDataType;
189             arrayBlockDesc[i].fSpecification=(*segment).fSpecification;
190             pDesc->SetActiveDataSegment(arrayBlockDesc[i].fOffset, arrayBlockDesc[i].fSize);
191             HLTDebug("component %p (%s) subscribed to segment #%d offset %d size %d data type %s %#x", 
192                      pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), i, arrayBlockDesc[i].fOffset,
193                      arrayBlockDesc[i].fSize, (AliHLTComponent::DataType2Text(arrayBlockDesc[i].fDataType)).c_str(), 
194                      arrayBlockDesc[i].fSpecification);
195             i++;
196             segment++;
197           }
198           // check whether there was enough space for the segments
199           if (i!=(int)tgtList.size()) {
200             HLTError("too little space in block descriptor array: required %d, available %d", tgtList.size(), iArraySize);
201             iResult=-ENOSPC;
202           } else {
203           // move this consumer to the active list
204           if (ChangeConsumerState(pDesc, fConsumers, fActiveConsumers)>=0) {
205             HLTDebug("component %p (%s) subscribed to data buffer %p", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this);
206           } else {
207             // TODO: cleanup the consumer descriptor correctly
208             memset(arrayBlockDesc, 0, iArraySize*sizeof(AliHLTComponentBlockData));
209             HLTError("can not activate consumer %p for data buffer %p", pConsumer, this);
210             iResult=-EACCES;
211           }
212           }
213         } else {
214           HLTError("unresolved data segment(s) for component %p (%s)", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID());
215           iResult=-EBADF;
216         }
217       } else {
218         HLTError("component %p is not a data consumer of data buffer %s", pConsumer, this);
219         iResult=-ENOENT;
220       }
221     } else {
222       // Matthias 26.07.2007 until now, data had to be present for successful subscription
223       // in order to be consistent with the PubSub framework, this restiction has been
224       // removed
225       //HLTError("data buffer %p is empty", this);
226       //iResult=-ENODATA;
227     }
228   } else {
229     HLTError("invalid parameter");
230     iResult=-EINVAL;
231   }
232   return iResult;
233 }
234
235 int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer)
236 {
237   // see header file for function documentation
238   int iResult=0;
239   if (pBlockDesc && pConsumer) {
240     AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fActiveConsumers);
241     if (pDesc) {
242       if ((iResult=pDesc->CheckActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize))!=1) {
243         HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize);
244         // TODO: appropriate error handling, but so far optional
245         iResult=0;
246       } else {
247         pDesc->ReleaseActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize);
248         pBlockDesc->fOffset=0;
249         pBlockDesc->fPtr=NULL;
250         pBlockDesc->fSize=0;
251       }
252       if (pDesc->GetNofActiveSegments()==0) {
253         if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
254           if (GetNofActiveConsumers()==0 && GetNofPendingConsumers()==0) {
255             // this is the last consumer, reset the consumer list and release the raw buffer
256             ResetDataBuffer();
257           }
258         } else {
259           HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
260           iResult=-EACCES;
261         }
262       }
263     } else {
264       HLTWarning("component %p has currently not subscribed to the data buffer %p", pConsumer, this);
265       iResult=-ENOENT;
266     }
267   } else {
268     HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
269     iResult=-EINVAL;
270   }
271   return iResult;
272 }
273
274 AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize)
275 {
276   // see header file for function documentation
277   AliHLTUInt8_t* pTargetBuffer=NULL;
278   if (fpBuffer!=NULL) {
279     HLTWarning("data buffer not properly reset, possible memory leak\n");
280   }
281   fpBuffer=CreateRawBuffer(iMinSize);
282   if (fpBuffer) {
283     pTargetBuffer=*fpBuffer;
284   } else {
285     HLTError("can not create raw buffer");
286   }
287   return pTargetBuffer;
288 }
289
290 int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arrayBlockData, int iSize)
291 {
292   // see header file for function documentation
293   int iResult=0;
294   if (pTgt && arrayBlockData && iSize>=0) {
295     if (fpBuffer) {
296       if (*fpBuffer==pTgt) {
297         AliHLTDataBuffer::AliHLTDataSegment segment;
298         for (int i=0; i<iSize; i++) {
299           // the pointer can be either NULL, than only the offset is considered, or a valid
300           // pointer in the range of the buffer
301           // The operator '>' includes the size of the buffer
302           if (arrayBlockData[i].fPtr==NULL ||
303               ((*fpBuffer)<=arrayBlockData[i].fPtr && (*fpBuffer)>arrayBlockData[i].fPtr)) {
304             int ptrOffset=0;
305             if (arrayBlockData[i].fPtr!=NULL) {
306               ptrOffset=(*fpBuffer)-arrayBlockData[i].fPtr;
307             }
308             if (arrayBlockData[i].fOffset+ptrOffset+arrayBlockData[i].fSize<=fpBuffer->fSize) {
309               segment.fSegmentOffset=arrayBlockData[i].fOffset+ptrOffset;
310               segment.fSegmentSize=arrayBlockData[i].fSize;
311               segment.fDataType=arrayBlockData[i].fDataType;
312               segment.fSpecification=arrayBlockData[i].fSpecification;
313               fSegments.push_back(segment);
314               HLTDebug("set segment %s with size %d at offset %d", AliHLTComponent::DataType2Text(segment.fDataType).data(), segment.fSegmentSize, segment.fSegmentOffset);
315             } else {
316               HLTError("block data specification %#d (%s) exceeds size of data buffer", i, AliHLTComponent::DataType2Text(arrayBlockData[i].fDataType).data());
317               HLTError("block offset=%d, block size=%d, buffer size=%d", arrayBlockData[i].fOffset, arrayBlockData[i].fSize, fpBuffer->fSize);
318               iResult=-E2BIG;
319             }
320           } else {
321             HLTError("invalid pointer (%p) in block data specification (buffer %p size %d)", arrayBlockData[i].fPtr, fpBuffer->fPtr, fpBuffer->fSize);
322             iResult=-ERANGE;
323           }
324         }
325       } else {
326         HLTError("this data buffer (%p) does not match the internal data buffer %p of raw buffer %p", pTgt, fpBuffer->fPtr, fpBuffer);
327         iResult=-EINVAL;
328       }
329     } else {
330       HLTFatal("internal data structur missmatch");
331       iResult=-EFAULT;
332     }
333   } else {
334     HLTError("invalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData);
335     iResult=-EINVAL;
336   }
337   return iResult;
338 }
339
340 int AliHLTDataBuffer::IsEmpty()
341 {
342   // see header file for function documentation
343   int iResult=fpBuffer==NULL || GetNofSegments()==0;
344   return iResult;
345 }
346
347 int AliHLTDataBuffer::GetNofSegments()
348 {
349   // see header file for function documentation
350   int iResult=fSegments.size();
351   return iResult;
352 }
353
354 int AliHLTDataBuffer::GetNofConsumers()
355 {
356   // see header file for function documentation
357   int iResult=fConsumers.size() + GetNofActiveConsumers() + fReleasedConsumers.size();
358   return iResult;
359 }
360
361 int AliHLTDataBuffer::GetNofPendingConsumers()
362 {
363   // see header file for function documentation
364   int iResult=fConsumers.size();
365   return iResult;
366 }
367
368 int AliHLTDataBuffer::GetNofActiveConsumers()
369 {
370   // see header file for function documentation
371   int iResult=fActiveConsumers.size();
372   return iResult;
373 }
374
375 AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::CreateRawBuffer(AliHLTUInt32_t size)
376 {
377   // see header file for function documentation
378   AliHLTRawBuffer* pRawBuffer=NULL;
379   unsigned int reqSize=size+fgkSafetyPatternSize;
380   vector<AliHLTRawBuffer*>::iterator buffer=fgFreeBuffers.begin();
381   while (buffer!=fgFreeBuffers.end() && pRawBuffer==NULL) {
382     if ((*buffer)->fTotalSize>=reqSize && ((*buffer)->fTotalSize-reqSize)<fgMargin) {
383       // assign this element
384       pRawBuffer=*buffer;
385       pRawBuffer->fSize=size;
386       fgFreeBuffers.erase(buffer);
387       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);
388       fgActiveBuffers.push_back(pRawBuffer);
389       break;
390     }
391     buffer++;
392   }
393   if (pRawBuffer==NULL) {
394     // no buffer found, create a new one
395     pRawBuffer=new AliHLTRawBuffer;
396     if (pRawBuffer) {
397       pRawBuffer->fPtr=static_cast<AliHLTUInt8_t*>(malloc(reqSize));
398       if (pRawBuffer->fPtr) {
399         pRawBuffer->fSize=size;
400         pRawBuffer->fTotalSize=reqSize;
401         fgActiveBuffers.push_back(pRawBuffer);
402         fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "new raw buffer %p of size %d created (container %p)", pRawBuffer->fPtr, pRawBuffer->fTotalSize, pRawBuffer);
403       } else {
404         delete pRawBuffer;
405         pRawBuffer=NULL;
406         fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed");
407       } 
408     } else {
409       fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed");
410     }
411   }
412   if (pRawBuffer!=NULL && fgkSafetyPatternSize>0) {
413     //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "writing safety pattern to %p offset %d", pRawBuffer->fPtr, pRawBuffer->fSize);
414     memcpy(((char*)pRawBuffer->fPtr)+pRawBuffer->fSize, fgkSafetyPattern, fgkSafetyPatternSize);
415   }
416   return pRawBuffer;
417 }
418
419 int AliHLTDataBuffer::ReleaseRawBuffer(AliHLTRawBuffer* pBuffer)
420 {
421   // see header file for function documentation
422   int iResult=0;
423   if (pBuffer) {
424     vector<AliHLTRawBuffer*>::iterator buffer=fgActiveBuffers.begin();
425     while (buffer!=fgActiveBuffers.end() && (*buffer)!=pBuffer) {
426       buffer++;
427     }
428     if (buffer!=fgActiveBuffers.end()) {
429       if (fgkSafetyPatternSize>0) {
430         //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "comparing safety pattern at %p offset %d", (*buffer)->fPtr, (*buffer)->fSize);
431         if (memcmp(((char*)(*buffer)->fPtr)+(*buffer)->fSize, fgkSafetyPattern, fgkSafetyPatternSize)!=0) {
432           fgLogging.Logging(kHLTLogFatal, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "component has written beyond end of data buffer %p size %d", (*buffer)->fPtr, (*buffer)->fSize);
433         }
434       }
435       (*buffer)->fSize=0;
436       fgFreeBuffers.push_back(*buffer);
437       fgActiveBuffers.erase(buffer);
438     } else {
439       fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "can not find raw buffer container %p in the list of active containers", pBuffer);
440       iResult=-ENOENT;
441     }
442   } else {
443     fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "invalid parameter");
444     iResult=-EINVAL;
445   }
446   return iResult;
447 }
448
449
450 int AliHLTDataBuffer::DeleteRawBuffers() 
451 {
452   // see header file for function documentation
453   int iResult=0;
454   vector<AliHLTRawBuffer*>::iterator buffer=fgFreeBuffers.begin();
455   while (buffer!=fgFreeBuffers.end()) {
456     free((*buffer)->fPtr);
457     delete *buffer;
458     fgFreeBuffers.erase(buffer);
459     buffer=fgFreeBuffers.begin();
460   }
461   buffer=fgActiveBuffers.begin();
462   while (buffer!=fgActiveBuffers.end()) {
463     fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "request to delete active raw buffer container (raw buffer %p, size %d)", (*buffer)->fPtr, (*buffer)->fTotalSize);
464     free((*buffer)->fPtr);
465     delete *buffer;
466     fgActiveBuffers.erase(buffer);
467     buffer=fgActiveBuffers.begin();
468   }
469   return iResult;
470 }
471
472 AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, vector<AliHLTConsumerDescriptor*> &list) const
473 {
474   // see header file for function documentation
475   AliHLTConsumerDescriptor* pDesc=NULL;
476   vector<AliHLTConsumerDescriptor*>::iterator desc=list.begin();
477   while (desc!=list.end() && pDesc==NULL) {
478     if ((pConsumer==NULL || (*desc)->GetComponent()==pConsumer)) {
479       pDesc=*desc;
480     }
481     desc++;
482   }
483   return pDesc;
484 }
485
486 int AliHLTDataBuffer::ResetDataBuffer() 
487 {
488   // see header file for function documentation
489   int iResult=0;
490   AliHLTRawBuffer* pBuffer=fpBuffer;
491   fpBuffer=NULL;
492
493   // cleanup consumer states
494   vector<AliHLTConsumerDescriptor*>::iterator desc;
495 //   if (GetNofPendingConsumers()>0) {
496 //     desc=fConsumers.begin();
497 //     while (desc!=fConsumers.end()) {
498 //       AliHLTComponent* pComp=(*desc)->GetComponent();
499 //       HLTError("internal error: consumer %p (%s %p) did not get data from data buffer %p", *desc, pComp?pComp->GetComponentID():"", pComp, this);
500 //       desc++;
501 //     }
502 //   }
503   desc=fReleasedConsumers.begin();
504   while (desc!=fReleasedConsumers.end()) {
505     AliHLTConsumerDescriptor* pDesc=*desc;
506     fReleasedConsumers.erase(desc);
507     desc=fReleasedConsumers.begin();
508     fConsumers.push_back(pDesc);
509   }
510   desc=fActiveConsumers.begin();
511   while (desc!=fActiveConsumers.end()) {
512     AliHLTConsumerDescriptor* pDesc=*desc;
513     HLTWarning("consumer %p was not released", pDesc);
514     fActiveConsumers.erase(desc);
515     desc=fActiveConsumers.begin();
516     fConsumers.push_back(pDesc);
517   }
518
519   // cleanup segments
520   vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=fSegments.begin();
521   while (segment!=fSegments.end()) {
522     fSegments.erase(segment);
523     segment=fSegments.begin();
524   }
525
526   // cleanup raw buffer
527   if (pBuffer) {
528     ReleaseRawBuffer(pBuffer);
529   }
530   return iResult;
531 }
532
533 int AliHLTDataBuffer::Reset()
534 {
535   // see header file for function documentation
536   return ResetDataBuffer();
537 }
538
539 // this is the version which works on lists of components instead of consumer descriptors
540 // int AliHLTDataBuffer::ChangeConsumerState(AliHLTComponent* pConsumer, vector<AliHLTComponent*> &srcList, vector<AliHLTComponent*> &tgtList)
541 // {
542 //   int iResult=0;
543 //   if (pDesc) {
544 //     vector<AliHLTComponent*>::iterator desc=srcList.begin();
545 //     while (desc!=srcList.end()) {
546 //       if ((*desc)==pConsumer) {
547 //      srcList.erase(desc);
548 //      tgtList.push_back(pConsumer);
549 //      break;
550 //       }
551 //      desc++;
552 //     }
553 //     if (desc==srcList.end()) {
554 //       HLTError("can not find consumer component %p in list", pConsumer);
555 //       iResult=-ENOENT;
556 //     }
557 //   } else {
558 //     HLTError("invalid parameter");
559 //     iResult=-EINVAL;
560 //   }
561 //   return iResult;
562 // }
563
564 int AliHLTDataBuffer::ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList)
565 {
566   // see header file for function documentation
567   int iResult=-ENOENT;
568   if (pDesc) {
569     vector<AliHLTConsumerDescriptor*>::iterator desc=srcList.begin();
570     while (desc!=srcList.end()) {
571       if ((*desc)==pDesc) {
572         srcList.erase(desc);
573         tgtList.push_back(pDesc);
574         iResult=0;
575         break;
576       }
577       desc++;
578     }
579     if (iResult<0) {
580       HLTError("can not find consumer descriptor %p in list", pDesc);
581     }
582   } else {
583     HLTError("invalid parameter");
584     iResult=-EINVAL;
585   }
586   return iResult;
587 }
588
589 int AliHLTDataBuffer::CleanupConsumerList() 
590 {
591   // see header file for function documentation
592   int iResult=0;
593   ResetDataBuffer();
594   vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin();
595   while (desc!=fConsumers.end()) {
596     delete *desc;
597     fConsumers.erase(desc);
598     desc=fConsumers.begin();
599   }
600   return iResult;
601 }
602
603 int AliHLTDataBuffer::FindConsumer(AliHLTComponent* pConsumer, int bAllLists)
604 {
605   // see header file for function documentation
606   vector<AliHLTConsumerDescriptor*>::iterator desc=fConsumers.begin();
607   while (desc!=fConsumers.end()) {
608     if ((*desc)->GetComponent()==pConsumer)
609       return 1;
610     desc++;
611   }
612   if (bAllLists==0) return 0;
613
614   desc=fActiveConsumers.begin();
615   while (desc!=fActiveConsumers.end()) {
616     if ((*desc)->GetComponent()==pConsumer)
617       return 1;
618     desc++;
619   }
620   desc=fReleasedConsumers.begin();
621   while (desc!=fReleasedConsumers.end()) {
622     if ((*desc)->GetComponent()==pConsumer)
623       return 1;
624     desc++;
625   }
626   return 0;
627 }
628
629 int AliHLTDataBuffer::AliHLTRawBuffer::operator==(void* ptr)
630 {
631   return fPtr == static_cast<AliHLTUInt8_t*>(ptr);
632 }
633
634 int AliHLTDataBuffer::AliHLTRawBuffer::operator<=(void* ptr)
635 {
636   int iResult=fPtr <= static_cast<AliHLTUInt8_t*>(ptr);
637   //printf("%p: %p <= %p (%d)\n", this, fPtr, ptr, iResult);
638   return iResult;
639 }
640
641 int AliHLTDataBuffer::AliHLTRawBuffer::operator>(void* ptr)
642 {
643   int iResult=fPtr+fSize > static_cast<AliHLTUInt8_t*>(ptr);
644   //printf("%p: %p + %d > %p (%d)\n", this, fPtr, fSize, ptr, iResult);
645   return iResult;
646 }
647
648 int AliHLTDataBuffer::AliHLTRawBuffer::operator-(void* ptr)
649 {
650   return static_cast<int>(static_cast<AliHLTUInt8_t*>(ptr)-fPtr);
651 }