implement block forwarding
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 13 Nov 2007 08:17:56 +0000 (08:17 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 13 Nov 2007 08:17:56 +0000 (08:17 +0000)
HLT/BASE/AliHLTConsumerDescriptor.cxx
HLT/BASE/AliHLTConsumerDescriptor.h
HLT/BASE/AliHLTDataBuffer.cxx
HLT/BASE/AliHLTDataBuffer.h
HLT/BASE/AliHLTTask.cxx
HLT/BASE/AliHLTTask.h

index 1d07bed..0ae25ea 100644 (file)
@@ -61,27 +61,26 @@ AliHLTConsumerDescriptor::~AliHLTConsumerDescriptor()
   }
 }
 
-int AliHLTConsumerDescriptor::SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
+int AliHLTConsumerDescriptor::SetActiveDataSegment(AliHLTDataBuffer::AliHLTDataSegment segment)
 {
   // see header file for function documentation
   int iResult=0;
-  AliHLTDataBuffer::AliHLTDataSegment segment(offset, size);
   fSegments.push_back(segment);
   //HLTDebug("set active segment (%d:%d) for consumer %p", offset, size, this);
   return iResult;
 }
 
-int AliHLTConsumerDescriptor::CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
+int AliHLTConsumerDescriptor::CheckActiveDataSegment(AliHLTDataBuffer::AliHLTDataSegment segment)
 {
   // see header file for function documentation
   int iResult=0;
   if (fSegments.size()>0) {
-    vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=fSegments.begin();
-    while (segment!=fSegments.end()) {
-      if ((iResult=((*segment).fSegmentOffset==offset && (*segment).fSegmentSize==size))>0) {
+    vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator element=fSegments.begin();
+    while (element!=fSegments.end()) {
+      if ((iResult=(segment==(*element)))>0) {
        break;
       }
-      segment++;
+      element++;
     }
   } else {
     //HLTWarning("no data segment active for consumer %p", this);
@@ -90,18 +89,18 @@ int AliHLTConsumerDescriptor::CheckActiveDataSegment(AliHLTUInt32_t offset, AliH
   return iResult;
 }
 
-int AliHLTConsumerDescriptor::ReleaseActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
+int AliHLTConsumerDescriptor::ReleaseActiveDataSegment(AliHLTDataBuffer::AliHLTDataSegment segment)
 {
   // see header file for function documentation
   int iResult=0;
   if (fSegments.size()>0) {
-    vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator segment=fSegments.begin();
-    while (segment!=fSegments.end()) {
-      if ((iResult=((*segment).fSegmentOffset==offset && (*segment).fSegmentSize==size))>0) {
-       fSegments.erase(segment);
+    vector<AliHLTDataBuffer::AliHLTDataSegment>::iterator element=fSegments.begin();
+    while (element!=fSegments.end()) {
+      if ((iResult=(segment==(*element)))>0) {
+       fSegments.erase(element);
        break;
       }
-      segment++;
+      element++;
     }
     if (iResult==0) {
       //HLTWarning("no data segment (%d:%d) active for consumer %p", offset, size, this);
index aa67835..fe05612 100644 (file)
@@ -48,20 +48,18 @@ class AliHLTConsumerDescriptor : public TObject, public AliHLTLogging {
    * Set an active data segment.
    * the pointer will be handled in a container, no allocation, copy or
    * cleanup.
-   * @param offset  offset of the segment in the buffer
-   * @param size    size of the segment in the buffer
+   * @param segment segment descriptor
    * @return >=0 if succeeded
    */
-  int SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
+  int SetActiveDataSegment(AliHLTDataBuffer::AliHLTDataSegment segment);
 
   /**
    * Check whether there is an active data segment of certain size with
    * certain offset.
-   * @param offset  offset of the data segment in the data buffer
-   * @param size    size of the data segment in the data buffer
+   * @param segment segment descriptor
    * @return > if existend, 0 if not
    */
-  int CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
+  int CheckActiveDataSegment(AliHLTDataBuffer::AliHLTDataSegment segment);
 
   /** find an active data segment of certain size with certain offset
    * will see if this is necessary
@@ -77,8 +75,9 @@ class AliHLTConsumerDescriptor : public TObject, public AliHLTLogging {
   int GetNofActiveSegments() {return fSegments.size();};
 
   /**
+   * @param segment segment descriptor
    */
-  int ReleaseActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
+  int ReleaseActiveDataSegment(AliHLTDataBuffer::AliHLTDataSegment segment);
 
  private:
   /** copy constructor prohibited */
index 5751583..4503d84 100644 (file)
@@ -35,6 +35,7 @@ using namespace std;
 #include "AliHLTDataBuffer.h"
 #include "AliHLTConsumerDescriptor.h"
 #include "AliHLTComponent.h"
+#include "AliHLTTask.h"
 #include <cerrno>
 #include <cassert>
 //#include <string>
@@ -53,7 +54,9 @@ AliHLTDataBuffer::AliHLTDataBuffer()
   fActiveConsumers(),
   fReleasedConsumers(),
   fpBuffer(NULL),
-  fFlags(0)
+  fFlags(0),
+  fForwardedSegmentSources(),
+  fForwardedSegments()
 {
   // see header file for class documentation
   // or
@@ -138,6 +141,9 @@ int AliHLTDataBuffer::FindMatchingDataSegments(const AliHLTComponent* pConsumer,
   // all blocks are passed to the consumer, which is the policy also in
   // PubSub
   tgtList.assign(fSegments.begin(), fSegments.end());
+
+  // add all forwarded blocks
+  tgtList.insert(tgtList.begin(), fForwardedSegments.begin(), fForwardedSegments.end());
   iResult=tgtList.size();
   return iResult;
   
@@ -169,7 +175,7 @@ int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponen
   // see header file for function documentation
   int iResult=0;
   if (pConsumer && arrayBlockDesc) {
-    if (fpBuffer) {
+    if (1/*fpBuffer*/) {
       AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fConsumers);
       if (pDesc) {
        AliHLTDataSegmentList tgtList;
@@ -190,14 +196,13 @@ int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponen
            // For incoming data blocks, fOffset must be ignored by the
            // processing component. It is set for bookkeeping in the framework.
            // fPtr always points to the beginning of the data.
-           arrayBlockDesc[i].fOffset=(*segment).fSegmentOffset;
-           AliHLTUInt8_t* pTgt=*fpBuffer;
-           pTgt+=(*segment).fSegmentOffset;
+           arrayBlockDesc[i].fOffset=0;
+           AliHLTUInt8_t* pTgt=*segment;
            arrayBlockDesc[i].fPtr=reinterpret_cast<void*>(pTgt);
            arrayBlockDesc[i].fSize=(*segment).fSegmentSize;
            arrayBlockDesc[i].fDataType=(*segment).fDataType;
            arrayBlockDesc[i].fSpecification=(*segment).fSpecification;
-           pDesc->SetActiveDataSegment(arrayBlockDesc[i].fOffset, arrayBlockDesc[i].fSize);
+           pDesc->SetActiveDataSegment(*segment);
            HLTDebug("component %p (%s) subscribed to segment #%d offset %d size %d data type %s %#x", 
                     pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), i, arrayBlockDesc[i].fOffset,
                     arrayBlockDesc[i].fSize, (AliHLTComponent::DataType2Text(arrayBlockDesc[i].fDataType)).c_str(), 
@@ -211,7 +216,10 @@ int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponen
            iResult=-ENOSPC;
          } else {
          // move this consumer to the active list
-         if (ChangeConsumerState(pDesc, fConsumers, fActiveConsumers)>=0) {
+         if (i==0) {
+           ChangeConsumerState(pDesc, fConsumers, fReleasedConsumers);
+           HLTDebug("no input data for component %p (%s) available", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID());
+         } else if (ChangeConsumerState(pDesc, fConsumers, fActiveConsumers)>=0) {
            HLTDebug("component %p (%s) subscribed to data buffer %p", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this);
          } else {
            // TODO: cleanup the consumer descriptor correctly
@@ -242,23 +250,54 @@ int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponen
   return iResult;
 }
 
-int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer)
+int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc,
+                             const AliHLTComponent* pConsumer,
+                             const AliHLTTask* pOwnerTask)
 {
   // see header file for function documentation
   int iResult=0;
   if (pBlockDesc && pConsumer) {
     AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fActiveConsumers);
     if (pDesc) {
-      if ((iResult=pDesc->CheckActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize))!=1) {
+      if ((iResult=pDesc->CheckActiveDataSegment(AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize)))!=1) {
        HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize);
        // TODO: appropriate error handling, but so far optional
        iResult=0;
       } else {
-       pDesc->ReleaseActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize);
-       pBlockDesc->fOffset=0;
-       pBlockDesc->fPtr=NULL;
-       pBlockDesc->fSize=0;
+       pDesc->ReleaseActiveDataSegment(AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize));
+      }
+      if (GetNofPendingConsumers()==0 && fForwardedSegments.size()>0) {
+       // last consumer, release forwarded segments
+       assert(fForwardedSegments.size()==fForwardedSegmentSources.size());
+       AliHLTDataSegmentList::iterator segment=fForwardedSegments.begin();
+       AliHLTTaskPList::iterator src=fForwardedSegmentSources.begin();
+       //HLTDebug("%p checking forwarded segments", this);
+       for (; segment!=fForwardedSegments.end(); segment++, src++) {
+         //HLTDebug("segment ptr=%p offset=%d size=%d\n"
+         //   "block ptr=%p offset=%d size=%d", (*segment).fPtr, (*segment).fSegmentOffset, (*segment).fSegmentSize, pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize);
+         if ((*segment)==AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize)) {
+           //HLTDebug("release segment of task %p", *src);
+           assert((*src)!=NULL);
+           if ((*src)!=NULL) {
+             if ((*src)->Release(pBlockDesc, pOwnerTask)>=0) {
+               HLTDebug("task %s (%p) released forwarded segment %p size %d of task %s (%p)",
+                        pOwnerTask->GetName(), pOwnerTask, (*segment).GetPtr(), (*segment).GetSize(),
+                        (*src)->GetName(), *src);
+             } else {
+               HLTError("task %s (%p) failed releasing forwarded segment %p size %d of task %s (%p)",
+                        pOwnerTask->GetName(), pOwnerTask, (*segment).GetPtr(), (*segment).GetSize(),
+                        (*src)->GetName(), *src);
+             }
+           }
+           fForwardedSegments.erase(segment);
+           fForwardedSegmentSources.erase(src);
+           break;
+         }
+       }
       }
+      pBlockDesc->fOffset=0;
+      pBlockDesc->fPtr=NULL;
+      pBlockDesc->fSize=0;
       if (pDesc->GetNofActiveSegments()==0) {
        if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
          if (GetNofActiveConsumers()==0 && GetNofPendingConsumers()==0) {
@@ -281,6 +320,17 @@ int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLT
   return iResult;
 }
 
+int AliHLTDataBuffer::Forward(AliHLTTask* pSrcTask, AliHLTComponentBlockData* pBlockDesc)
+{
+  // see header file for function documentation
+  if (pSrcTask==NULL || pBlockDesc==NULL) return -EINVAL;
+  assert(fForwardedSegments.size()==fForwardedSegmentSources.size());
+  if (fForwardedSegments.size()!=fForwardedSegmentSources.size()) return -EFAULT;
+  fForwardedSegmentSources.push_back(pSrcTask);
+  fForwardedSegments.push_back(AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize));
+  return 0;
+}
+
 AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize)
 {
   // see header file for function documentation
@@ -309,11 +359,14 @@ int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData*
          // This function has to model the behavior of PubSub
          // For output blocks only the fOffset value is used, this must be the offset
          // relative to the output pointer. fPtr must be either NULL or the output
-         // pointer
+         // pointer. In either case it is 'ignored' and set to the beginning of the
+         // data buffer
          if (arrayBlockData[i].fPtr==NULL ||
              arrayBlockData[i].fPtr==*fpBuffer) {
+           arrayBlockData[i].fPtr=*fpBuffer;
            if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<=fpBuffer->GetUsedSize()) {
              segment.fSegmentOffset=arrayBlockData[i].fOffset;
+             segment.fPtr=(AliHLTUInt8_t*)arrayBlockData[i].fPtr;
              segment.fSegmentSize=arrayBlockData[i].fSize;
              segment.fDataType=arrayBlockData[i].fDataType;
              segment.fSpecification=arrayBlockData[i].fSpecification;
@@ -498,6 +551,11 @@ int AliHLTDataBuffer::ResetDataBuffer()
   AliHLTRawBuffer* pBuffer=fpBuffer;
   fpBuffer=NULL;
 
+  // cleanup forwarded segment lists
+  assert(fForwardedSegments.size()==0);
+  fForwardedSegments.clear();
+  fForwardedSegmentSources.clear();
+
   // cleanup consumer states
   AliHLTConsumerDescriptorPList::iterator desc;
 //   if (GetNofPendingConsumers()>0) {
index 0e3702b..280eab9 100644 (file)
 #include "AliHLTComponent.h"
 
 class AliHLTConsumerDescriptor;
+class AliHLTTask;
 
 /** list of AliHLTConsumerDescriptor pointers */
 typedef vector<AliHLTConsumerDescriptor*> AliHLTConsumerDescriptorPList;
 
+typedef AliHLTUInt8_t* AliHLTUInt8Pointer_t;
+
 /**
  * @class AliHLTDataBuffer
  * @brief  Handling of data buffers for the HLT.
@@ -115,12 +118,24 @@ class AliHLTDataBuffer : public TObject, public AliHLTLogging
    * The method is used by the consumer component.
    * @param pBlockDesc      descriptor of the data segment
    * @param pConsumer       the component which subscribes to the buffer
+   * @param pOwnerTask      task owning this buffer
    * @return: >0 if success, negative error code if failed <br>
    *          -EACCESS      the consumer state can not be changed (de-activated)
    *          -ENOENT       consumer has not subscribed to the buffer <br>
    *          -EINVAL       invalid parameter <br>
    */
-  int Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer);
+  int Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTComponent* pConsumer,
+             const AliHLTTask* pOwnerTask);
+
+  /**
+   * Register an input data block for forwarding.
+   * Consumer of this data buffer subscribe to forwarded data blocks in te same way.
+   * Forwarded data blocks are released when the last consumer has released the
+   * blocks.
+   * @param pSrcTask        original source task of the data block
+   * @param pBlockDesc      descriptor of the data segment
+   */
+  int Forward(AliHLTTask* pSrcTask, AliHLTComponentBlockData* pBlockDesc);
 
   /**
    * Get a target buffer of minimum size iMinSize.
@@ -211,31 +226,64 @@ class AliHLTDataBuffer : public TObject, public AliHLTLogging
    * @brief  Descriptor of a data segment within the buffer.
    */
   class AliHLTDataSegment {
-  friend class AliHLTDataBuffer;
-  friend class AliHLTConsumerDescriptor;
+    friend class AliHLTDataBuffer;
+    friend class AliHLTConsumerDescriptor;
   public:
     AliHLTDataSegment()
       :
-      fDataType(),
+      fDataType(kAliHLTVoidDataType),
+      fPtr(NULL),
       fSegmentOffset(0),
       fSegmentSize(0),
       fSpecification(0)
     {
-      memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
     }
-    AliHLTDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size) 
+
+    AliHLTDataSegment(AliHLTUInt8_t* ptr, AliHLTUInt32_t offset, AliHLTUInt32_t size) 
+      :
+      fDataType(kAliHLTVoidDataType),
+      fPtr(ptr),
+      fSegmentOffset(offset),
+      fSegmentSize(size),
+      fSpecification(0)
+    {
+    }
+
+    AliHLTDataSegment(void* ptr, AliHLTUInt32_t offset, AliHLTUInt32_t size) 
       :
-      fDataType(),
+      fDataType(kAliHLTVoidDataType),
+      fPtr((AliHLTUInt8_t*)ptr),
       fSegmentOffset(offset),
       fSegmentSize(size),
       fSpecification(0)
     {
-      memset(&fDataType, 0, sizeof(AliHLTComponentDataType));
     }
 
+    AliHLTDataSegment(void* ptr, AliHLTUInt32_t offset, AliHLTUInt32_t size, AliHLTComponentDataType dt, AliHLTUInt32_t spec)
+      :
+      fDataType(dt),
+      fPtr((AliHLTUInt8_t*)ptr),
+      fSegmentOffset(offset),
+      fSegmentSize(size),
+      fSpecification(spec)
+    {
+    }
+
+    AliHLTUInt8_t* GetPtr() const {return (AliHLTUInt8_t*)*this;}
+
+    AliHLTUInt32_t GetSize() const {return fSegmentSize;}
+    
+    int operator==(const AliHLTDataSegment& seg) const
+    {
+      return (fPtr+fSegmentOffset==seg.fPtr+seg.fSegmentOffset) && (fSegmentSize==seg.fSegmentSize);
+    }
+    operator AliHLTUInt8_t*() const {return fPtr+fSegmentOffset;}
+
   private:
     /** the data type of this segment */
     AliHLTComponentDataType fDataType;                             // see above
+    /** pointer to the buffer */
+    AliHLTUInt8Pointer_t fPtr;                                     //!transient
     /** offset in byte within the data buffer */
     AliHLTUInt32_t fSegmentOffset;                                 // see above
     /** size of the actual content */
@@ -373,6 +421,12 @@ class AliHLTDataBuffer : public TObject, public AliHLTLogging
   // flags indicating the state of the buffer
   AliHLTUInt32_t fFlags;                                           // see above
 
+  /** list of tasks with forwarded data blocks */
+  vector<AliHLTTask*> fForwardedSegmentSources;                    //! transient
+
+  /** list of forwarded block descriptors */
+  vector<AliHLTDataSegment> fForwardedSegments;                    //! transient
+
   //////////////////////////////////////////////////////////////////////////////
   // global buffer handling, internal use only
 
index 6a57a34..2e1dacd 100644 (file)
@@ -33,6 +33,7 @@ using namespace std;
 #endif
 
 #include <cerrno>
+#include <cassert>
 #include <iostream>
 #include <string>
 #include "AliHLTTask.h"
@@ -438,7 +439,7 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
     int iInputDataVolume=0;
 
     AliHLTTask* pSrcTask=NULL;
-    TList subscribedTaskList;
+    AliHLTTaskPList subscribedTaskList;
     TObjLink* lnk=fListDependencies.FirstLink();
 
     // subscribe to all source tasks
@@ -464,7 +465,7 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
            iInputDataVolume+=fBlockDataArray[i+iSourceDataBlock].fSize;
            // put the source task as many times into the list as it provides data blocks
            // makes the bookkeeping for the data release easier
-           subscribedTaskList.Add(pSrcTask);
+           subscribedTaskList.push_back(pSrcTask);
          }
          HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
          iSourceDataBlock+=iResult;      
@@ -515,8 +516,25 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
        iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
        HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt);
-       if (iResult>=0 && pTgtBuffer && outputBlocks) {
-         iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
+       if (iResult>=0 && outputBlocks) {
+         AliHLTComponentBlockDataList segments;
+         for (int oblock=0; oblock<outputBlockCnt; oblock++) {
+           int iblock=0;
+           for (; iblock<evtData.fBlockCnt; iblock++) {
+             if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
+               assert(subscribedTaskList[iblock]!=NULL);
+               if (subscribedTaskList[iblock]==NULL) continue;
+               HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
+               fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
+               subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
+               break;
+             }
+           }
+           if (iblock==evtData.fBlockCnt) segments.push_back(outputBlocks[oblock]);
+         }
+         if (pTgtBuffer && segments.size()>0) {
+           iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
+         }
          delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
        } else {
          fpDataBuffer->Reset();
@@ -530,9 +548,9 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
 
     // now release all buffers which we have subscribed to
     iSourceDataBlock=0;
-    lnk=subscribedTaskList.FirstLink();
-    while (lnk) {
-      pSrcTask=(AliHLTTask*)lnk->GetObject();
+    AliHLTTaskPList::iterator element;
+    while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
+      pSrcTask=*element;
       if (pSrcTask) {
        int iTempRes=0;
        if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
@@ -540,15 +558,11 @@ int AliHLTTask::ProcessTask(Int_t eventNo)
        } else {
          HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
        }
-      } else {
-       HLTFatal("task %s (%p): internal error in ROOT list handling", GetName(), this);
-       if (iResult>=0) iResult=-EFAULT;
       }
-      subscribedTaskList.Remove(lnk);
-      lnk=subscribedTaskList.FirstLink();
+      subscribedTaskList.erase(element);
       iSourceDataBlock++;
     }
-    if (subscribedTaskList.GetSize()>0) {
+    if (subscribedTaskList.size()>0) {
       HLTError("task %s (%p): could not release all data buffers", GetName(), this);
     }
   } else {
@@ -621,7 +635,7 @@ int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask*
   int iResult=0;
   if (pConsumerTask && pBlockDesc) {
     if (fpDataBuffer) {
-      iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent());
+      iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
     } else {
       HLTFatal("internal data buffer missing");
       iResult=-EFAULT;
index 87f76dd..b528f0c 100644 (file)
@@ -19,6 +19,7 @@
 // or
 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt   
 
+#include <vector>
 #include <TObject.h>
 #include <TList.h>
 #include "AliHLTDataTypes.h"
@@ -29,6 +30,9 @@ struct AliHLTComponentBlockData;
 class AliHLTComponent;
 class AliHLTComponentHandler;
 class AliHLTConfiguration;
+class AliHLTTask;
+
+typedef vector<AliHLTTask*> AliHLTTaskPList;
 
 /******************************************************************************/