]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
bugfix https://savannah.cern.ch/bugs/?55067
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 2 Sep 2009 01:10:49 +0000 (01:10 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 2 Sep 2009 01:10:49 +0000 (01:10 +0000)
Updating AliHLTMessage to TMessage r27689

HLT encountered a problem when streaming the AliESDEvent. The problem occurs if the
TClonesArray members contain more then one entry. In this case, members of the individual
objects have been mixed.

The problem turned out to be solely on the serialization part, and did not effect the
restoration part. This has been proven by using either TMessage and AliHLTMessage on the
sender, and only AliHLTMessage on the receiver side. Merging the recent changes in
TMessage solved the issue.

HLT/BASE/AliHLTMessage.cxx
HLT/BASE/AliHLTMessage.h

index 687e33f346b7546e52794a1faa8cd8438f674b5f..75cc551c02a9d38887bbea1f950474890479620b 100644 (file)
 //////////////////////////////////////////////////////////////////////////
 
 #include "AliHLTMessage.h"
+#include "TVirtualStreamerInfo.h"
 #include "Bytes.h"
 #include "TFile.h"
+#include "TProcessID.h"
 #include "TClass.h"
 
 extern "C" void R__zip (Int_t cxlevel, Int_t *nin, char *bufin, Int_t *lout, char *bufout, Int_t *nout);
 extern "C" void R__unzip(Int_t *nin, UChar_t *bufin, Int_t *lout, char *bufout, Int_t *nout);
 const Int_t kMAXBUF = 0xffffff;
 
+Bool_t AliHLTMessage::fgEvolution = kFALSE;
+
 ClassImp(AliHLTMessage)
 
 //______________________________________________________________________________
@@ -55,6 +59,9 @@ AliHLTMessage::AliHLTMessage(UInt_t what)
   fBufCompCur(0),
   fCompPos(0)
   , fBufUncompressed(0)
+  , fBitsPIDs(0)
+  , fInfos(NULL)
+  , fEvolution(kFALSE)
 {
    // Create a AliHLTMessage object for storing objects. The "what" integer
    // describes the type of message. Predifined ROOT system message types
@@ -72,6 +79,7 @@ AliHLTMessage::AliHLTMessage(UInt_t what)
 
    *this << what;
 
+   SetBit(kCannotHandleMemberWiseStreaming);
 }
 
 const Int_t AliHLTMessage::fgkMinimumSize=30;
@@ -93,6 +101,9 @@ AliHLTMessage::AliHLTMessage(void *buf, Int_t bufsize)
   fBufCompCur(0),
   fCompPos(0)
   , fBufUncompressed(0)
+  , fBitsPIDs(0)
+  , fInfos(NULL)
+  , fEvolution(kFALSE)
 {
    // Create a AliHLTMessage object for reading objects. The objects will be
    // read from buf. Use the What() method to get the message type.
@@ -134,6 +145,34 @@ AliHLTMessage::~AliHLTMessage()
   Reset();
 }
 
+//______________________________________________________________________________
+void AliHLTMessage::EnableSchemaEvolutionForAll(Bool_t enable)
+{
+   // Static function enabling or disabling the automatic schema evolution.
+   // By default schema evolution support is off.
+
+   fgEvolution = enable;
+}
+
+//______________________________________________________________________________
+Bool_t AliHLTMessage::UsesSchemaEvolutionForAll()
+{
+   // Static function returning status of global schema evolution.
+
+   return fgEvolution;
+}
+
+//______________________________________________________________________________
+void AliHLTMessage::ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t /* force */)
+{
+   // Force writing the TStreamerInfo to the message.
+
+   if (fgEvolution || fEvolution) {
+      if (!fInfos) fInfos = new TList();
+      fInfos->Add(info);
+   }
+}
+
 //______________________________________________________________________________
 void AliHLTMessage::Forward()
 {
@@ -143,6 +182,7 @@ void AliHLTMessage::Forward()
    if (IsReading()) {
       SetWriteMode();
       SetBufferOffset(fBufSize);
+      SetBit(kCannotHandleMemberWiseStreaming);
 
       if (fBufComp) {
          fCompPos = fBufCur;
@@ -150,6 +190,19 @@ void AliHLTMessage::Forward()
    }
 }
 
+//______________________________________________________________________________
+void AliHLTMessage::IncrementLevel(TVirtualStreamerInfo *info)
+{
+   // Increment level.
+
+   TBufferFile::IncrementLevel(info);
+
+   if (fgEvolution || fEvolution) {
+      if (!fInfos) fInfos = new TList();
+      fInfos->Add(info);
+   }
+}
+
 //______________________________________________________________________________
 void AliHLTMessage::Reset()
 {
@@ -346,6 +399,47 @@ Int_t AliHLTMessage::Uncompress()
    return 0;
 }
 
+//______________________________________________________________________________
+void AliHLTMessage::WriteObject(const TObject *obj)
+{
+   // Write object to message buffer.
+   // When support for schema evolution is enabled the list of TStreamerInfo
+   // used to stream this object is kept in fInfos. This information is used
+   // by TSocket::Send that sends this list through the socket. This list is in
+   // turn used by TSocket::Recv to store the TStreamerInfo objects in the
+   // relevant TClass in case the TClass does not know yet about a particular
+   // class version. This feature is implemented to support clients and servers
+   // with either different ROOT versions or different user classes versions.
+
+   if (fgEvolution || fEvolution) {
+      if (fInfos)
+         fInfos->Clear();
+      else
+         fInfos = new TList();
+   }
+
+   fBitsPIDs.ResetAllBits();
+   WriteObjectAny(obj, TObject::Class());
+}
+
+//______________________________________________________________________________
+UShort_t AliHLTMessage::WriteProcessID(TProcessID *pid)
+{
+   // Check if the ProcessID pid is already in the message.
+   // If not, then:
+   //   - mark bit 0 of fBitsPIDs to indicate that a ProcessID has been found
+   //   - mark bit uid+1 where uid id the uid of the ProcessID
+
+   if (fBitsPIDs.TestBitNumber(0)) return 0;
+   if (!pid)
+      pid = TProcessID::GetPID();
+   if (!pid) return 0;
+   fBitsPIDs.SetBitNumber(0);
+   UInt_t uid = pid->GetUniqueID();
+   fBitsPIDs.SetBitNumber(uid+1);
+   return 1;
+}
+
 AliHLTMessage* AliHLTMessage::Stream(TObject* pSrc, Int_t compression, unsigned verbosity)
 {
   /// Helper function to stream an object into an AliHLTMessage
index 6561b9c14f6533c3cd8979e45af95228e2755526..f75d172fedbca5d470145fbb60222ff229700933 100644 (file)
@@ -9,6 +9,14 @@
 // modifications, original revision:
 // root/net: v5-14-00 $: TMessage.h,v 1.9 2005/12/09 15:12:19 rdm
 // Author: Fons Rademakers   19/12/96
+//
+// 2009-09-01 updating to revision
+// @(#)root/net:$Id$
+// Streaming problems have been encountered, especially when streaming
+// TObjArrays. As long as there was just one member, the streaming was
+// fine. With several members, internal variables of the objects have
+// been interchanged/mixed. This bug only effected the serialization
+// part, not the restoration of the object.
 
 /*************************************************************************
  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
@@ -41,6 +49,9 @@
 #ifndef ROOT_MessageTypes
 #include "MessageTypes.h"
 #endif
+#ifndef ROOT_TBits
+#include "TBits.h"
+#endif
 
 #include "AliHLTLogging.h"
 /**
@@ -113,19 +124,28 @@ public:
 
    void SetLength() const;
 
+   void     ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force);
    void     Forward();
-   TClass  *GetClass() const { return fClass; }
+   TClass  *GetClass() const { return fClass;}
+   void     IncrementLevel(TVirtualStreamerInfo* info);
    void     Reset();
    void     Reset(UInt_t what) { SetWhat(what); Reset(); }
    UInt_t   What() const { return fWhat; }
    void     SetWhat(UInt_t what);
 
+   void     EnableSchemaEvolution(Bool_t enable = kTRUE) { fEvolution = enable; }
+   Bool_t   UsesSchemaEvolution() const { return fEvolution; }
    void     SetCompressionLevel(Int_t level = 1);
    Int_t    GetCompressionLevel() const { return fCompress; }
    Int_t    Compress();
    Int_t    Uncompress();
    char    *CompBuffer() const { return fBufComp; }
    Int_t    CompLength() const { return (Int_t)(fBufCompCur - fBufComp); }
+   void     WriteObject(const TObject *obj);
+   UShort_t WriteProcessID(TProcessID *pid);
+
+   static void   EnableSchemaEvolutionForAll(Bool_t enable = kTRUE);
+   static Bool_t UsesSchemaEvolutionForAll();
 
    /**
     * Helper function to stream an object into an AliHLTMessage
@@ -147,6 +167,11 @@ private:
    char    *fBufCompCur;  //!Current position in compressed buffer
    char    *fCompPos;     //!Position of fBufCur when message was compressed
    char    *fBufUncompressed; //!Uncompressed buffer
+   TBits    fBitsPIDs;    //Array of bits to mark the TProcessIDs uids written to the message
+   TList   *fInfos;       //Array of TStreamerInfo used in WriteObject
+   Bool_t   fEvolution;   //True if support for schema evolution required
+
+   static Bool_t fgEvolution;  //True if global support for schema evolution required
 
    // AliHLTMessage objects cannot be copied or assigned
    AliHLTMessage(const AliHLTMessage &);           // not implemented
@@ -158,7 +183,7 @@ private:
    /** a default buffer describing an empty message */
    static UInt_t fgkDefaultBuffer[2]; //!transient
 
-   ClassDef(AliHLTMessage,1)  // Message buffer class
+   ClassDef(AliHLTMessage,2)  // Message buffer class
 };
 
 #endif // ALIHLTMESSAGE_H