ROOT logo
// $Id$

//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        * 
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/** @file   AliHLTDumpTask.cxx
    @author Matthias Richter
    @date   
    @brief  Base class for data sinks with direct buffer access.
*/

#include "AliHLTDumpTask.h"

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTDumpTask)

AliHLTDumpTask::AliHLTDumpTask(const char* chains)
  :
  AliHLTTask(),
  fpDummyTask(NULL),
  fpDummyConfiguration(NULL),
  fBlocks()
{
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
  if (chains && chains[0]!=0) SetChains(chains);
}

AliHLTDumpTask::~AliHLTDumpTask()
{
  // see header file for class documentation

  // UnsetTarget called automatically
  if (fpDummyTask) delete fpDummyTask;
  fpDummyTask=NULL;

  if (fpDummyConfiguration) delete fpDummyConfiguration;
  fpDummyConfiguration=NULL;

  if (fpConfiguration) delete fpConfiguration;
  fpConfiguration=NULL;
}

int AliHLTDumpTask::SetChains(const char* chains)
{
  // see header file for class documentation
  if (!chains || chains[0]==0) {
    HLTError("invalid chain id string");
    return -EINVAL;
  }
  TString taskname=chains;
  taskname.ReplaceAll(" ", "_");
  taskname+="_hltDumpTask";

  // This is just a trick to use the existing Task handling, especially the
  // ProcessTask function.
  // 1. The 'BlockFilter' just forwards the data blocks of all specified chains
  // 2. A dummy task is added to the target list in order to set the data segments
  //    after forwarding. In case of an empty target list the data is just discarded.
  // That's maybe not the most elegant solution but far less awkward as one would
  // expect.
  fpConfiguration=new AliHLTConfiguration(taskname.Data(), "BlockFilter", chains, NULL);
  TString dummyname=chains;
  dummyname.ReplaceAll(" ", "_");
  dummyname+="_never_used_dummy_";
  fpDummyConfiguration=new AliHLTConfiguration(dummyname.Data(), "BlockFilter", taskname.Data(), NULL);
  if (fpDummyConfiguration) {
    fpDummyTask=new AliHLTTask(fpDummyConfiguration);
    SetTarget(fpDummyTask);
  }
  return 0;
}

int AliHLTDumpTask::CustomInit(AliHLTComponentHandler* pCH)
{
  // see header file for class documentation
  if (!fpDummyTask) return -ENOENT;
  return fpDummyTask->Init(NULL, pCH);
}

int AliHLTDumpTask::CustomCleanup()
{
  // see header file for class documentation
  if (!fpDummyTask) return -ENOENT;
  return fpDummyTask->Deinit();
}

const char* AliHLTDumpTask::GetSourceChains() const
{
  // see header file for class documentation
  if (!fpConfiguration) return "";
  return fpConfiguration->GetSourceSettings();
}

const AliHLTComponentBlockDataList& AliHLTDumpTask::GetDataBlocks()
{
  // see header file for class documentation
  if (fBlocks.size()>0) return fBlocks;
  if (fpDataBuffer) {
    if (!fpDataBuffer->FindConsumer(fpDummyTask->GetComponent())) {
      // in order to subscribe to the buffers the dummy consumer
      // needs to be set. The dummy task is not in the AliHLTSystem chain
      // and therefor not automatically set.
      fpDataBuffer->SetConsumer(fpDummyTask->GetComponent());
    }
    fBlocks.clear();
    if (fpDataBuffer->GetNofSegments()>0 
	&& fpDataBuffer->FindConsumer(fpDummyTask->GetComponent(), 0 /*search only among pending consumers*/)>0) {
      if (fpDataBuffer->Subscribe(fpDummyTask->GetComponent(), fBlocks)>=0) {
	return fBlocks;
      } else {
	HLTError("failed to subscribe to data buffer");
      }
    }
  } else {
    // 2008-08-07 this is not a failure condition
    // If the chain has not been processed because LocalReconstruction
    // is not enabled, the task will be empty
    //HLTWarning("no data buffer available");
  }
  fBlocks.clear();
  return fBlocks;
}

int AliHLTDumpTask::ReleaseDataBlocks()
{
  // see header file for class documentation
  int iResult=0;
  if (!fpDataBuffer) return 0;

  if (fBlocks.size()==0 && fpDataBuffer->GetNofPendingConsumers()>0) {
    // There are data blocks in the parents which this task has not yet
    // subscribed to. The subscription takes place in GetDataBlocks.
    // However, this method is not necessarily called.
    //
    // In order to switch buffer states correctly, first let the dummy
    // task as the only consumer subscribe to all those buffers and
    // release them further down. Basically, the buffers are arranged
    // in a different internal list, which is the only state they can be
    // released from. This approach has been chosen to implement the
    // DumpTask having no real consumers but at the same time has to
    // behave like a normal task in AliHLTTask::ProcessTask
    fpDataBuffer->Subscribe(fpDummyTask->GetComponent(), fBlocks);
  }

  for (unsigned int i=0; i<fBlocks.size(); i++) {
    fpDataBuffer->Release(&(fBlocks[i]), fpDummyTask->GetComponent(), this);
  }
  fBlocks.clear();
  return iResult;
}
 AliHLTDumpTask.cxx:1
 AliHLTDumpTask.cxx:2
 AliHLTDumpTask.cxx:3
 AliHLTDumpTask.cxx:4
 AliHLTDumpTask.cxx:5
 AliHLTDumpTask.cxx:6
 AliHLTDumpTask.cxx:7
 AliHLTDumpTask.cxx:8
 AliHLTDumpTask.cxx:9
 AliHLTDumpTask.cxx:10
 AliHLTDumpTask.cxx:11
 AliHLTDumpTask.cxx:12
 AliHLTDumpTask.cxx:13
 AliHLTDumpTask.cxx:14
 AliHLTDumpTask.cxx:15
 AliHLTDumpTask.cxx:16
 AliHLTDumpTask.cxx:17
 AliHLTDumpTask.cxx:18
 AliHLTDumpTask.cxx:19
 AliHLTDumpTask.cxx:20
 AliHLTDumpTask.cxx:21
 AliHLTDumpTask.cxx:22
 AliHLTDumpTask.cxx:23
 AliHLTDumpTask.cxx:24
 AliHLTDumpTask.cxx:25
 AliHLTDumpTask.cxx:26
 AliHLTDumpTask.cxx:27
 AliHLTDumpTask.cxx:28
 AliHLTDumpTask.cxx:29
 AliHLTDumpTask.cxx:30
 AliHLTDumpTask.cxx:31
 AliHLTDumpTask.cxx:32
 AliHLTDumpTask.cxx:33
 AliHLTDumpTask.cxx:34
 AliHLTDumpTask.cxx:35
 AliHLTDumpTask.cxx:36
 AliHLTDumpTask.cxx:37
 AliHLTDumpTask.cxx:38
 AliHLTDumpTask.cxx:39
 AliHLTDumpTask.cxx:40
 AliHLTDumpTask.cxx:41
 AliHLTDumpTask.cxx:42
 AliHLTDumpTask.cxx:43
 AliHLTDumpTask.cxx:44
 AliHLTDumpTask.cxx:45
 AliHLTDumpTask.cxx:46
 AliHLTDumpTask.cxx:47
 AliHLTDumpTask.cxx:48
 AliHLTDumpTask.cxx:49
 AliHLTDumpTask.cxx:50
 AliHLTDumpTask.cxx:51
 AliHLTDumpTask.cxx:52
 AliHLTDumpTask.cxx:53
 AliHLTDumpTask.cxx:54
 AliHLTDumpTask.cxx:55
 AliHLTDumpTask.cxx:56
 AliHLTDumpTask.cxx:57
 AliHLTDumpTask.cxx:58
 AliHLTDumpTask.cxx:59
 AliHLTDumpTask.cxx:60
 AliHLTDumpTask.cxx:61
 AliHLTDumpTask.cxx:62
 AliHLTDumpTask.cxx:63
 AliHLTDumpTask.cxx:64
 AliHLTDumpTask.cxx:65
 AliHLTDumpTask.cxx:66
 AliHLTDumpTask.cxx:67
 AliHLTDumpTask.cxx:68
 AliHLTDumpTask.cxx:69
 AliHLTDumpTask.cxx:70
 AliHLTDumpTask.cxx:71
 AliHLTDumpTask.cxx:72
 AliHLTDumpTask.cxx:73
 AliHLTDumpTask.cxx:74
 AliHLTDumpTask.cxx:75
 AliHLTDumpTask.cxx:76
 AliHLTDumpTask.cxx:77
 AliHLTDumpTask.cxx:78
 AliHLTDumpTask.cxx:79
 AliHLTDumpTask.cxx:80
 AliHLTDumpTask.cxx:81
 AliHLTDumpTask.cxx:82
 AliHLTDumpTask.cxx:83
 AliHLTDumpTask.cxx:84
 AliHLTDumpTask.cxx:85
 AliHLTDumpTask.cxx:86
 AliHLTDumpTask.cxx:87
 AliHLTDumpTask.cxx:88
 AliHLTDumpTask.cxx:89
 AliHLTDumpTask.cxx:90
 AliHLTDumpTask.cxx:91
 AliHLTDumpTask.cxx:92
 AliHLTDumpTask.cxx:93
 AliHLTDumpTask.cxx:94
 AliHLTDumpTask.cxx:95
 AliHLTDumpTask.cxx:96
 AliHLTDumpTask.cxx:97
 AliHLTDumpTask.cxx:98
 AliHLTDumpTask.cxx:99
 AliHLTDumpTask.cxx:100
 AliHLTDumpTask.cxx:101
 AliHLTDumpTask.cxx:102
 AliHLTDumpTask.cxx:103
 AliHLTDumpTask.cxx:104
 AliHLTDumpTask.cxx:105
 AliHLTDumpTask.cxx:106
 AliHLTDumpTask.cxx:107
 AliHLTDumpTask.cxx:108
 AliHLTDumpTask.cxx:109
 AliHLTDumpTask.cxx:110
 AliHLTDumpTask.cxx:111
 AliHLTDumpTask.cxx:112
 AliHLTDumpTask.cxx:113
 AliHLTDumpTask.cxx:114
 AliHLTDumpTask.cxx:115
 AliHLTDumpTask.cxx:116
 AliHLTDumpTask.cxx:117
 AliHLTDumpTask.cxx:118
 AliHLTDumpTask.cxx:119
 AliHLTDumpTask.cxx:120
 AliHLTDumpTask.cxx:121
 AliHLTDumpTask.cxx:122
 AliHLTDumpTask.cxx:123
 AliHLTDumpTask.cxx:124
 AliHLTDumpTask.cxx:125
 AliHLTDumpTask.cxx:126
 AliHLTDumpTask.cxx:127
 AliHLTDumpTask.cxx:128
 AliHLTDumpTask.cxx:129
 AliHLTDumpTask.cxx:130
 AliHLTDumpTask.cxx:131
 AliHLTDumpTask.cxx:132
 AliHLTDumpTask.cxx:133
 AliHLTDumpTask.cxx:134
 AliHLTDumpTask.cxx:135
 AliHLTDumpTask.cxx:136
 AliHLTDumpTask.cxx:137
 AliHLTDumpTask.cxx:138
 AliHLTDumpTask.cxx:139
 AliHLTDumpTask.cxx:140
 AliHLTDumpTask.cxx:141
 AliHLTDumpTask.cxx:142
 AliHLTDumpTask.cxx:143
 AliHLTDumpTask.cxx:144
 AliHLTDumpTask.cxx:145
 AliHLTDumpTask.cxx:146
 AliHLTDumpTask.cxx:147
 AliHLTDumpTask.cxx:148
 AliHLTDumpTask.cxx:149
 AliHLTDumpTask.cxx:150
 AliHLTDumpTask.cxx:151
 AliHLTDumpTask.cxx:152
 AliHLTDumpTask.cxx:153
 AliHLTDumpTask.cxx:154
 AliHLTDumpTask.cxx:155
 AliHLTDumpTask.cxx:156
 AliHLTDumpTask.cxx:157
 AliHLTDumpTask.cxx:158
 AliHLTDumpTask.cxx:159
 AliHLTDumpTask.cxx:160
 AliHLTDumpTask.cxx:161
 AliHLTDumpTask.cxx:162
 AliHLTDumpTask.cxx:163
 AliHLTDumpTask.cxx:164
 AliHLTDumpTask.cxx:165
 AliHLTDumpTask.cxx:166
 AliHLTDumpTask.cxx:167