fix coding convention violations
[u/mrichter/AliRoot.git] / RAW / AliMDC.cxx
CommitLineData
a197a4ce 1// @(#)alimdc:$Name$:$Id$
2// Author: Fons Rademakers 26/11/99
3// Updated: Dario Favretto 15/04/2003
4
5/**************************************************************************
6 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
7 * *
8 * Author: The ALICE Off-line Project. *
9 * Contributors are mentioned in the code where appropriate. *
10 * *
11 * Permission to use, copy, modify and distribute this software and its *
12 * documentation strictly for non-commercial purposes is hereby granted *
13 * without fee, provided that the above copyright notice appears in all *
14 * copies and that both the copyright notice and this permission notice *
15 * appear in the supporting documentation. The authors make no claims *
16 * about the suitability of this software for any purpose. It is *
17 * provided "as is" without express or implied warranty. *
18 **************************************************************************/
19
20//////////////////////////////////////////////////////////////////////////
21// //
22// AliMDC //
23// //
24// Set of classes defining the ALICE RAW event format. The AliRawEvent //
25// class defines a RAW event. It consists of an AliEventHeader object //
26// an AliEquipmentHeader object, an AliRawData object and an array of //
27// sub-events, themselves also being AliRawEvents. The number of //
28// sub-events depends on the number of DATE LDC's. //
29// The AliRawEvent objects are written to a ROOT file using different //
30// technologies, i.e. to local disk via AliRawDB or via rfiod using //
31// AliRawRFIODB or via rootd using AliRawRootdDB or to CASTOR via //
32// rootd using AliRawCastorDB (and for performance testing there is //
33// also AliRawNullDB). //
34// The AliRunDB class provides the interface to the run and file //
35// catalogues (AliEn or plain MySQL). //
36// The AliStats class provides statics information that is added as //
37// a single keyed object to each raw file. //
38// The AliTagDB provides an interface to a TAG database. //
39// The AliMDC class is usid by the "alimdc" stand-alone program //
40// that reads data directly from DATE. //
41// //
42//////////////////////////////////////////////////////////////////////////
43
44#include <errno.h>
45
46#include <TSystem.h>
47#include <TError.h>
48#include <TStopwatch.h>
49
50#ifdef ALI_DATE
51#include "event.h"
52#endif
53#ifdef USE_EB
54#include "libDateEb.h"
55#endif
56
57#include "AliRawEvent.h"
58#include "AliRawEventHeader.h"
59#include "AliRawEquipmentHeader.h"
60#include "AliRawData.h"
61#include "AliStats.h"
62#include "AliRawDB.h"
63#include "AliRawRFIODB.h"
64#include "AliRawCastorDB.h"
65#include "AliRawRootdDB.h"
66#include "AliRawNullDB.h"
67#include "AliTagDB.h"
68
69#include "AliMDC.h"
70
71
72ClassImp(AliMDC)
73
74
75#define ALIDEBUG(level) \
76 if (AliMDC::Instance() && (AliMDC::Instance()->GetDebugLevel() >= (level)))
77
78
79// Fixed file system locations for the different DB's
80#ifdef USE_RDM
81const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo";
82const char* const AliMDC::fgkRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
83const char* const AliMDC::fgkTagDBFS = "/tmp/mdc1/tags";
84const char* const AliMDC::fgkRunDBFS = "/tmp/mdc1/meta";
85const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/user/r/rdm";
86const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/user/r/rdm";
87const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1";
88const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct";
89const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC";
90#else
91const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo";
92const char* const AliMDC::fgkRawDBFS[2] = { "/data1/mdc", "/data2/mdc" };
93const char* const AliMDC::fgkTagDBFS = "/data1/mdc/tags";
94const char* const AliMDC::fgkRunDBFS = "/data1/mdc/meta";
95const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/lcg/dc5";
96const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/lcg/dc5";
97const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1";
98const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct";
99const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC";
100#endif
101
102// Maximum size of tag db files
103const Double_t AliMDC::fgkMaxTagFileSize = 2.5e8; // 250MB
104
105Bool_t AliMDC::fgDeleteFiles = kFALSE;
106AliMDC* AliMDC::fgInstance = NULL;
107
108
109//______________________________________________________________________________
110AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter,
111 EWriteMode mode, Bool_t useLoop, Bool_t delFiles)
112{
113 // Create MDC processor object.
114
115 fFd = fd;
116 fCompress = compress;
117 fMaxFileSize = maxFileSize;
118 fUseFilter = useFilter;
119 fWriteMode = mode;
120 fUseLoop = useLoop;
121 fUseFifo = kFALSE;
122 fUseEb = kFALSE;
123 fStopLoop = kFALSE;
124 fNumEvents = 0;
125 fDebugLevel = 0;
126 fgDeleteFiles = delFiles;
127
128 if (fFd == -1) {
129#ifdef USE_EB
130 if (!ebRegister()) {
131 Error("AliMDC", "cannot register with the event builder (%s)",
132 ebGetLastError());
133 return;
134 }
135 fUseEb = kTRUE;
136#else
137 if ((mkfifo(fgkFifo, 0644) < 0) && (errno != EEXIST)) {
138 Error("AliMDC", "cannot create fifo %s", fgkFifo);
139 return;
140 }
141 if ((chmod(fgkFifo, 0666) == -1) && (errno != EPERM)) {
142 Error("AliMDC", "cannot change permission of fifo %s", fgkFifo);
143 return;
144 }
145 if ((fFd = open(fgkFifo, O_RDONLY)) == -1) {
146 Error("AliMDC", "cannot open input file %s", fgkFifo);
147 return;
148 }
149 fUseFifo = kTRUE;
150#endif
151 fUseLoop = kFALSE;
152 }
153
154 printf("<AliMDC::AliMDC>: input = %s, rawdb size = %f, filter = %s, "
155 "looping = %s, compression = %d, delete files = %s",
156 fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize,
157 fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress,
158 fgDeleteFiles ? "yes" : "no");
159 if (fWriteMode == kRFIO)
160 printf(", use RFIO\n");
161 else if (fWriteMode == kROOTD)
162 printf(", use rootd\n");
163 else if (fWriteMode == kCASTOR)
164 printf(", use CASTOR/rootd\n");
165 else if (fWriteMode == kDEVNULL)
166 printf(", write raw data to /dev/null\n");
167 else
168 printf("\n");
169
170 // install SIGUSR1 handler to allow clean interrupts
171 gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
172
173 fgInstance = this;
174}
175
176//______________________________________________________________________________
177AliMDC::AliMDC(const AliMDC& mdc): TObject(mdc)
178{
179// copy constructor
180
181 Fatal("AliMDC", "copy constructor not implemented");
182}
183
184//______________________________________________________________________________
185AliMDC& AliMDC::operator = (const AliMDC& /*mdc*/)
186{
187// assignment operator
188
189 Fatal("operator =", "assignment operator not implemented");
190 return *this;
191}
192
193//______________________________________________________________________________
194Int_t AliMDC::Run()
195{
196 // Run the MDC processor. Read from the input stream and only return
197 // when the input gave and EOF or a fatal error occured. On success 0
198 // is returned, 1 in case of a fatality.
199
200 TStopwatch timer;
201 Int_t status;
202
203 // Make sure needed directories exist
204 const char *dirs[4];
205 dirs[0] = fgkRawDBFS[0];
206 dirs[1] = fgkRawDBFS[1];
207 dirs[2] = fgkTagDBFS;
208 dirs[3] = fgkRunDBFS;
209 for (int idir = 0; idir < 4; idir++) {
210 gSystem->ResetErrno();
211 gSystem->MakeDirectory(dirs[idir]);
212 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
213 SysError("Run", "mkdir %s", dirs[idir]);
214 return 1;
215 }
216 }
217
218 // Used for statistics
219 timer.Start();
220 Double_t told = 0, tnew = 0;
221 Float_t chunkSize = fMaxFileSize/100, nextChunk = chunkSize;
222
223 // Event object used to store event data.
224 AliRawEvent *event = new AliRawEvent;
225
226 // Create new raw DB.
227 AliRawDB *rawdb;
228 if (fWriteMode == kRFIO)
229 rawdb = new AliRawRFIODB(event, fMaxFileSize, fCompress);
230 else if (fWriteMode == kROOTD)
231 rawdb = new AliRawRootdDB(event, fMaxFileSize, fCompress);
232 else if (fWriteMode == kCASTOR)
233 rawdb = new AliRawCastorDB(event, fMaxFileSize, fCompress);
234 else if (fWriteMode == kDEVNULL)
235 rawdb = new AliRawNullDB(event, fMaxFileSize, fCompress);
236 else
237 rawdb = new AliRawDB(event, fMaxFileSize, fCompress);
238
239 if (rawdb->IsZombie()) return 1;
240 printf("Filling raw DB %s\n", rawdb->GetDBName());
241
242 // Create new tag DB.
243 AliTagDB *tagdb = 0;
244#if 0
245 // no tagdb for the time being to get maximum speed
246 if (fWriteMode == fgkDEVNULL)
247 tagdb = new AliTagNullDB(event->GetHeader(), fgkMaxTagFileSize);
248 else
249 tagdb = new AliTagDB(event->GetHeader(), fgkMaxTagFileSize);
250 if (tagdb->IsZombie())
251 tagdb = 0;
252 else
253 printf("Filling tag DB %s\n", tagdb->GetDBName());
254#endif
255
256 // Create AliStats object
257 AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
258
259 // Shortcut for easy header access
260 AliRawEventHeader &header = *event->GetHeader();
261
262 // Process input stream
263#ifdef USE_EB
264 Int_t eorFlag = 0;
265 while (!(eorFlag = ebEor())) {
266 struct iovec *ebvec;
267 if ((ebvec = ebGetNextEvent()) == (void *)-1) {
268 Error("Run", "error getting next event (%s)", ebGetLastError());
269 break;
270 }
271 if (ebvec == 0) {
272 // no event, sleep for 1 second and try again
273 gSystem->Sleep(1000);
274 continue;
275 }
276 char *ebdata = (char *) ebvec[0].iov_base;
277#else
278 while (1) {
279 char *ebdata = 0;
280#endif
281
282 // Read event header
283 if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) {
284 if (status == 0) {
285 if (fUseLoop) {
286#ifndef USE_EB
287 ::lseek(fFd, 0, SEEK_SET);
288#endif
289 continue;
290 }
291 printf("<AliMDC::Run>: EOF, processed %d events\n", fNumEvents);
292 break;
293 }
294 return 1;
295 }
296 ALIDEBUG(3)
297 header.Dump();
298
299 // If we were in looping mode stop directly after a SIGUSR1 signal
300 if (StopLoop()) {
301 Info("Run", "Stopping loop, processed %d events", fNumEvents);
302 break;
303 }
304
305 // Check if event has any hard track flagged
306 Bool_t callFilter = kFALSE;
307 // This needs to be re-engineered for the next ADC...
308 //if (fUseFilter && TEST_USER_ATTRIBUTE(header.GetTypeAttribute(), 0))
309 // callFilter = kTRUE;
310
311 // Check event type and skip "Start of Run", "End of Run",
312 // "Start of Run Files" and "End of Run Files"
313 switch (header.GetType()) {
314 case AliRawEventHeader::kStartOfRun:
315 case AliRawEventHeader::kEndOfRun:
316 case AliRawEventHeader::kStartOfRunFiles:
317 case AliRawEventHeader::kEndOfRunFiles:
318 {
319 Int_t skip = header.GetEventSize() - header.HeaderSize();
320#ifndef USE_EB
321 ::lseek(fFd, skip, SEEK_CUR);
322#endif
323 ALIDEBUG(1)
324 Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
325 continue;
326 }
327 default:
328 ALIDEBUG(1) {
329 Int_t s = header.GetEventSize() - header.HeaderSize();
330 Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s);
331 }
332 }
333
334 // Amount of data left to read for this event
335 Int_t toRead = header.GetEventSize() - header.HeaderSize();
336
337 // If there is less data for this event than the next sub-event
338 // header, something is wrong. Skip to next event...
339 if (toRead < header.HeaderSize()) {
340 ALIDEBUG(1) {
341 Warning("Run",
342 "header size (%d) exceeds number of bytes to read (%d)\n",
343 header.HeaderSize(), toRead);
344 header.Dump();
345 }
346 if ((status = DumpEvent(toRead)) != toRead) {
347 if (status == 0)
348 break;
349 return 1;
350 }
351 Error("Run", "discarding event %d (too little data for header)", fNumEvents);
352 continue;
353 }
354
355 // Loop over all sub-events... (LDCs)
356 Int_t nsub = 1;
357 while (toRead > 0) {
358#ifdef USE_EB
359 ebdata = (char *)ebvec[nsub].iov_base;
360#endif
361
362 ALIDEBUG(1)
363 Info("Run", "reading LDC %d", nsub);
364
365 AliRawEvent *subEvent = event->NextSubEvent();
366
367 // Read sub-event header
368 AliRawEventHeader &subHeader = *subEvent->GetHeader();
369 if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) {
370 if (status == 0) {
371 Error("Run", "unexpected EOF reading sub-event header");
372 break;
373 }
374 return 1;
375 }
376
377 ALIDEBUG(3)
378 subHeader.Dump();
379
380 toRead -= subHeader.HeaderSize();
381
382#ifdef USE_EB
383 ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize();
384#endif
385
386 Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize();
387
388 // Read Equipment Header (in case of physics or calibration event)
389 if (header.GetType() == AliRawEventHeader::kPhysicsEvent ||
390 header.GetType() == AliRawEventHeader::kCalibrationEvent) {
391 AliRawEquipmentHeader &equipment = *subEvent->GetEquipmentHeader();
392 Int_t equipHeaderSize = equipment.HeaderSize();
393 if ((status = ReadEquipmentHeader(equipment, header.DataIsSwapped(),
394 ebdata)) != equipHeaderSize) {
395 if (status == 0) {
396 Error("Run", "unexpected EOF reading equipment-header");
397 break;
398 }
399 return 1;
400 }
401 toRead -= equipHeaderSize;
402 rawSize -= equipHeaderSize;
403#ifdef USE_EB
404 ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize() +
405 equipHeaderSize;
406#endif
407 }
408
409 // Make sure raw data less than left over bytes for current event
410 if (rawSize > toRead) {
411 ALIDEBUG(1) {
412 Warning("Run", "raw data size (%d) exceeds number of bytes "
413 "to read (%d)\n", rawSize, toRead);
414 subHeader.Dump();
415 }
416 if ((status = DumpEvent(toRead)) != toRead) {
417 if (status == 0)
418 break;
419 return 1;
420 }
421 Error("Run", "discarding event %d (too much data)", fNumEvents);
422 continue;
423 }
424
425 // Read sub-event raw data
426 AliRawData &subRaw = *subEvent->GetRawData();
427 if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) {
428 if (status == 0) {
429 Error("Run", "unexpected EOF reading sub-event raw data");
430 break;
431 }
432 return 1;
433 }
434
435 if (callFilter) {
436#ifdef ALI_DATE
437 if (TEST_USER_ATTRIBUTE(subHeader.GetTypeAttribute(), 0))
438 Filter(subRaw);
439 else {
440 // set size of all sectors without hard track flag to 0
441 subRaw.SetSize(0);
442 }
443#endif
444 }
445
446 toRead -= rawSize;
447 nsub++;
448 }
449
450 // Set stat info for first event of this file
451 if (rawdb->GetEvents() == 0)
452 stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun());
453
454 // Store raw event in tree
455 rawdb->Fill();
456
457 // Store header in tree
458 if (tagdb) tagdb->Fill();
459
460 fNumEvents++;
461
462 if (!(fNumEvents%10))
463 printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents());
464
465 // Filling time statistics
466 if (rawdb->GetBytesWritten() > nextChunk) {
467 tnew = timer.RealTime();
468 stats->Fill(tnew-told);
469 told = tnew;
470 timer.Continue();
471 nextChunk += chunkSize;
472 }
473
474 // Check size of raw db. If bigger than maxFileSize, close file
475 // and continue with new file.
476 if (rawdb->FileFull()) {
477
478 printf("Written raw DB at a rate of %.1f MB/s\n",
479 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
480
481 // Write stats object to raw db, run db, MySQL and AliEn
482 stats->WriteToDB(rawdb);
483 delete stats;
484
485 if (!rawdb->NextFile()) {
486 Error("Run", "error opening next raw data file");
487 return 1;
488 }
489
490 printf("Filling raw DB %s\n", rawdb->GetDBName());
491 stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
492
493 timer.Start();
494 told = 0, tnew = 0;
495 nextChunk = chunkSize;
496 }
497
498 // Check size of tag db
499 if (tagdb && tagdb->FileFull()) {
500 if (!tagdb->NextFile())
501 tagdb = 0;
502 else
503 printf("Filling tag DB %s\n", tagdb->GetDBName());
504 }
505
506 // Make top event object ready for next event data
507 //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents());
508 event->Reset();
509
510#ifdef USE_EB
511 if (!ebReleaseEvent(ebvec)) {
512 Error("Run", "problem releasing event (%s)", ebGetLastError());
513 break;
514 }
515#endif
516 }
517
518 printf("Written raw DB at a rate of %.1f MB/s\n",
519 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
520
521 // Write stats to raw db and run db and delete stats object
522 stats->WriteToDB(rawdb);
523 delete stats;
524
525 // Close the raw DB
526 delete rawdb;
527
528 // Close the tag DB
529 delete tagdb;
530
531 // Close input source
532 close(fFd);
533
534#if 0
535 // Cleanup fifo
536 if (fUseFifo && ::unlink(fgkFifo) == -1) {
537 SysError("Run", "unlink");
538 return 1;
539 }
540#endif
541
542#ifdef USE_EB
543 // Print eor flag
544 if (eorFlag) {
545 Info("Run", "event builder reported end of run (%d)", eorFlag);
546 }
547#endif
548
549 return 0;
550}
551
552//______________________________________________________________________________
553Int_t AliMDC::Read(void *buffer, Int_t length)
554{
555 // Read exactly length bytes into buffer. Returns number of bytes
556 // received, returns -1 in case of error and 0 for EOF.
557
558 errno = 0;
559
560 if (fFd < 0) return -1;
561
562 Int_t n, nrecv = 0;
563 char *buf = (char *)buffer;
564
565 for (n = 0; n < length; n += nrecv) {
566 if ((nrecv = read(fFd, buf+n, length-n)) <= 0) {
567 if (nrecv == 0)
568 break; // EOF
569 if (errno != EINTR)
570 SysError("Read", "read");
571 return -1;
572 }
573 }
574 return n;
575}
576
577//______________________________________________________________________________
578Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb)
579{
580 // Read header info from DATE data stream. Returns bytes read (i.e.
581 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
582
583 Int_t nrecv;
584
585 if (eb) {
586 // read from event builder memory area
587 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
588 nrecv = header.HeaderSize();
589 } else {
590 // read from fifo or file
591 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
592 header.HeaderSize()) {
593 if (nrecv == 0)
594 return 0;
595 return -1;
596 }
597 }
598
599 // Swap header data if needed
600 if (header.IsSwapped())
601 header.Swap();
602
603 // Is header valid...
604 if (!header.IsValid()) {
605 Error("ReadHeader", "invalid header format");
606 // try recovery... how?
607 return -1;
608 }
609 if (header.GetEventSize() < (UInt_t)header.HeaderSize()) {
610 Error("ReadHeader", "invalid header size");
611 // try recovery... how?
612 return -1;
613 }
614
615 return nrecv;
616}
617
618//______________________________________________________________________________
619Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
620 Bool_t isSwapped, void *eb)
621{
622 // Read equipment header info from DATE data stream. Returns bytes read
623 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
624 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
625 // and we will swap the header to host format.
626
627 Int_t nrecv;
628
629 if (eb) {
630 // read from event builder memory area
631 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
632 nrecv = header.HeaderSize();
633 } else {
634 // read from fifo or file
635 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
636 header.HeaderSize()) {
637 if (nrecv == 0)
638 return 0;
639 return -1;
640 }
641 }
642
643 // Swap equipment header data if needed
644 if (isSwapped)
645 header.Swap();
646
647 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
648 Error("ReadEquipmentHeader", "invalid equipment header size");
649 // try recovery... how?
650 return -1;
651 }
652
653 return nrecv;
654}
655
656//______________________________________________________________________________
657Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb)
658{
659 // Read raw data from DATE data stream. Returns bytes read (i.e.
660 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
661
662 Int_t nrecv;
663
664 if (eb) {
665 // read from event builder memory area
666 raw.SetBuffer(eb, size);
667 nrecv = size;
668 } else {
669 // read from fifo or file
670 raw.SetSize(size);
671 if ((nrecv = Read(raw.GetBuffer(), size)) != size) {
672 if (nrecv == 0) {
673 Error("ReadRawData", "unexpected EOF");
674 return 0;
675 }
676 return -1;
677 }
678 }
679
680 return nrecv;
681}
682
683//______________________________________________________________________________
684Int_t AliMDC::DumpEvent(Int_t toRead)
685{
686 // This case should not happen, but if it does try to handle it
687 // gracefully by reading the rest of the event and discarding it.
688 // Returns bytes read, -1 in case of fatal error and 0 for EOF.
689
690 Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents);
691
692 Int_t nrecv;
693 char *tbuf = new char[toRead];
694 if ((nrecv = Read(tbuf, toRead)) != toRead) {
695 if (nrecv == 0) {
696 Error("DumpEvent", "unexpected EOF");
697 return 0;
698 }
699 return -1;
700 }
701 delete [] tbuf;
702
703 return nrecv;
704}
705
706//______________________________________________________________________________
707Int_t AliMDC::Filter(AliRawData &raw)
708{
709 // Call 3rd level filter for this raw data segment.
710
711#ifdef USE_HLT
712
713 // Add HLT code here
714
715#else
716
717 raw.GetSize();
718 printf("Filter called for event %d\n", fNumEvents);
719
720#endif
721
722 return 0;
723}
724
725//______________________________________________________________________________
726AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const
727 AliMDCInterruptHandler&
728 handler):
729 TSignalHandler(handler)
730{
731// copy constructor
732
733 Fatal("AliMDCInterruptHandler", "copy constructor not implemented");
734}
735
736//______________________________________________________________________________
737AliMDC::AliMDCInterruptHandler&
738 AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler&
739 /*handler*/)
740{
741// assignment operator
742
743 Fatal("operator =", "assignment operator not implemented");
744 return *this;
745}