// @(#)root/io:$Id$
// Author: Fons Rademakers   08/07/97

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TMapFile
#define ROOT_TMapFile


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMapFile                                                             //
//                                                                      //
// This class implements a shared memory region mapped to a file.       //
// Objects can be placed into this shared memory area using the Add()   //
// member function. Whenever the mapped object(s) change(s) call        //
// Update() to put a fresh copy in the shared memory. This extra        //
// step is necessary since it is not possible to share objects with     //
// virtual pointers between processes (the vtbl ptr points to the       //
// originators unique address space and can not be used by the          //
// consumer process(es)). Consumer processes can map the memory region  //
// from this file and access the objects stored in it via the Get()     //
// method (which returns a copy of the object stored in the shared      //
// memory with correct vtbl ptr set). Only objects of classes with a    //
// Streamer() member function defined can be shared.                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef WIN32
#include "Windows4Root.h"
#endif
#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TROOT
#include "TROOT.h"
#endif
#if !defined(__MMPRIVATE_H) && !defined(__CINT__)
#include "mmprivate.h"
#endif


class TBrowser;
class TDirectory;
class TList;
class TMapRec;

class TMapFile : public TObject {

friend class TMapRec;

private:
   Int_t       fFd;             //Descriptor of mapped file
   Int_t       fVersion;        //ROOT version (or -1 for shadow map file)
   char       *fName;           //Name of mapped file
   char       *fTitle;          //Title of mapped file
   char       *fOption;         //Directory creation options
   void       *fMmallocDesc;    //Pointer to mmalloc descriptor
   ULong_t     fBaseAddr;       //Base address of mapped memory region
   Int_t       fSize;           //Original start size of memory mapped region
   TMapRec    *fFirst;          //List of streamed objects is shared memory
   TMapRec    *fLast;           //Last object in list of shared objects
   Long_t      fOffset;         //Offset in bytes for region mapped by reader
   TDirectory *fDirectory;      //Pointer to directory associated to this mapfile
   TList      *fBrowseList;     //List of KeyMapFile objects
   Bool_t      fWritable;       //TRUE if mapped file opened in RDWR mode
   Int_t       fSemaphore;      //Modification semaphore (or getpid() for WIN32)
   ULong_t     fhSemaphore;     //HANDLE of WIN32 Mutex object to implement semaphore
   TObject    *fGetting;        //Don't deadlock in update mode, when from Get() Add() is called
   Int_t       fWritten;        //Number of objects written sofar
   Double_t    fSumBuffer;      //Sum of buffer sizes of objects written sofar
   Double_t    fSum2Buffer;     //Sum of squares of buffer sizes of objects written so far

   static Long_t fgMapAddress;  //Map to this address, set address via SetMapAddress()
   static void  *fgMmallocDesc; //Used in Close() and operator delete()

protected:
   TMapFile();
   TMapFile(const char *name, const char *title, Option_t *option, Int_t size, TMapFile *&newMapFile);
   TMapFile(const TMapFile &f, Long_t offset = 0);
   void       operator=(const TMapFile &rhs);  // not implemented

   TMapFile  *FindShadowMapFile();
   void       InitDirectory();
   TObject   *Remove(TObject *obj, Bool_t lock);
   TObject   *Remove(const char *name, Bool_t lock);
   void       SumBuffer(Int_t bufsize);
   Int_t      GetBestBuffer();

   void   CreateSemaphore(Int_t pid=0);
   Int_t  AcquireSemaphore();
   Int_t  ReleaseSemaphore();
   void   DeleteSemaphore();

   static void *MapToAddress();

public:
   enum { kDefaultMapSize = 0x80000 }; // default size of mapped heap is 500 KB

   // Should both be protected (waiting for cint)
   virtual ~TMapFile();
   void     operator delete(void *vp);

   void          Browse(TBrowser *b);
   void          Close(Option_t *option = "");
   void         *GetBaseAddr() const { return (void *)fBaseAddr; }
   void         *GetBreakval() const;
   TDirectory   *GetDirectory() const {return fDirectory;}
   Int_t         GetFd() const { return fFd; }
   void         *GetMmallocDesc() const { return fMmallocDesc; }
   const char   *GetName() const { return fName; }
   Int_t         GetSize() const { return fSize; }
   const char   *GetOption() const { return fOption; }
   const char   *GetTitle() const { return fTitle; }
   TMapRec      *GetFirst() const { return (TMapRec*)((Long_t) fFirst + fOffset); }
   TMapRec      *GetLast() const { return (TMapRec*)((Long_t) fLast + fOffset); }
   Bool_t        IsFolder() const;
   Bool_t        IsWritable() const { return fWritable; }
   void         *OrgAddress(void *addr) const { return (void *)((Long_t)addr - fOffset); }
   void          Print(Option_t *option="") const;
   void          ls(Option_t *option="") const;
   Bool_t        cd(const char *path = 0);

   void          Add(const TObject *obj, const char *name = "");
   void          Update(TObject *obj = 0);
   TObject      *Remove(TObject *obj) { return Remove(obj, kTRUE); }
   TObject      *Remove(const char *name) { return Remove(name, kTRUE); }
   void          RemoveAll();
   TObject      *Get(const char *name, TObject *retObj = 0);

   static TMapFile *Create(const char *name, Option_t *option="READ", Int_t size=kDefaultMapSize, const char *title="");
   static TMapFile *WhichMapFile(void *addr);
   static void      SetMapAddress(Long_t addr);

   ClassDef(TMapFile,0)  // Memory mapped directory structure
};



//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMapRec                                                              //
//                                                                      //
// A TMapFile contains a list of TMapRec objects which keep track of    //
// the actual objects stored in the mapped file.                        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TMapRec {

friend class TMapFile;

private:
   char            *fName;       // object name
   char            *fClassName;  // class name
   TObject         *fObject;     // pointer to original object
   void            *fBuffer;     // buffer containing object of class name
   Int_t            fBufSize;    // buffer size
   TMapRec         *fNext;       // next MapRec in list

   TMapRec(const TMapRec&);            // Not implemented.
   TMapRec &operator=(const TMapRec&); // Not implemented.

public:
   TMapRec(const char *name, const TObject *obj, Int_t size, void *buf);
   ~TMapRec();
   const char   *GetName(Long_t offset = 0) const { return (char *)((Long_t) fName + offset); }
   const char   *GetClassName(Long_t offset = 0) const { return (char *)((Long_t) fClassName + offset); }
   void         *GetBuffer(Long_t offset = 0) const { return (void *)((Long_t) fBuffer + offset); }
   Int_t         GetBufSize() const { return fBufSize; }
   TObject      *GetObject() const;
   TMapRec      *GetNext(Long_t offset = 0) const { return (TMapRec *)((Long_t) fNext + offset); }
};


//______________________________________________________________________________
inline void *TMapFile::GetBreakval() const
{
   // Return the current location in the memory region for this malloc heap which
   // represents the end of memory in use. Returns 0 if map file was closed.

   if (!fMmallocDesc) return 0;
   return (void *)((struct mdesc *)fMmallocDesc)->breakval;
}

//______________________________________________________________________________
inline TMapFile *TMapFile::WhichMapFile(void *addr)
{
   if (!gROOT || !gROOT->GetListOfMappedFiles()) return 0;

   TObjLink *lnk = ((TList *)gROOT->GetListOfMappedFiles())->LastLink();
   while (lnk) {
      TMapFile *mf = (TMapFile*)lnk->GetObject();
      if (!mf) return 0;
      if ((ULong_t)addr >= mf->fBaseAddr + mf->fOffset &&
          (ULong_t)addr <  (ULong_t)mf->GetBreakval() + mf->fOffset)
         return mf;
      lnk = lnk->Prev();
   }
   return 0;
}

R__EXTERN void *gMmallocDesc;  //is initialized in TClass.cxx

#endif
 TMapFile.h:1
 TMapFile.h:2
 TMapFile.h:3
 TMapFile.h:4
 TMapFile.h:5
 TMapFile.h:6
 TMapFile.h:7
 TMapFile.h:8
 TMapFile.h:9
 TMapFile.h:10
 TMapFile.h:11
 TMapFile.h:12
 TMapFile.h:13
 TMapFile.h:14
 TMapFile.h:15
 TMapFile.h:16
 TMapFile.h:17
 TMapFile.h:18
 TMapFile.h:19
 TMapFile.h:20
 TMapFile.h:21
 TMapFile.h:22
 TMapFile.h:23
 TMapFile.h:24
 TMapFile.h:25
 TMapFile.h:26
 TMapFile.h:27
 TMapFile.h:28
 TMapFile.h:29
 TMapFile.h:30
 TMapFile.h:31
 TMapFile.h:32
 TMapFile.h:33
 TMapFile.h:34
 TMapFile.h:35
 TMapFile.h:36
 TMapFile.h:37
 TMapFile.h:38
 TMapFile.h:39
 TMapFile.h:40
 TMapFile.h:41
 TMapFile.h:42
 TMapFile.h:43
 TMapFile.h:44
 TMapFile.h:45
 TMapFile.h:46
 TMapFile.h:47
 TMapFile.h:48
 TMapFile.h:49
 TMapFile.h:50
 TMapFile.h:51
 TMapFile.h:52
 TMapFile.h:53
 TMapFile.h:54
 TMapFile.h:55
 TMapFile.h:56
 TMapFile.h:57
 TMapFile.h:58
 TMapFile.h:59
 TMapFile.h:60
 TMapFile.h:61
 TMapFile.h:62
 TMapFile.h:63
 TMapFile.h:64
 TMapFile.h:65
 TMapFile.h:66
 TMapFile.h:67
 TMapFile.h:68
 TMapFile.h:69
 TMapFile.h:70
 TMapFile.h:71
 TMapFile.h:72
 TMapFile.h:73
 TMapFile.h:74
 TMapFile.h:75
 TMapFile.h:76
 TMapFile.h:77
 TMapFile.h:78
 TMapFile.h:79
 TMapFile.h:80
 TMapFile.h:81
 TMapFile.h:82
 TMapFile.h:83
 TMapFile.h:84
 TMapFile.h:85
 TMapFile.h:86
 TMapFile.h:87
 TMapFile.h:88
 TMapFile.h:89
 TMapFile.h:90
 TMapFile.h:91
 TMapFile.h:92
 TMapFile.h:93
 TMapFile.h:94
 TMapFile.h:95
 TMapFile.h:96
 TMapFile.h:97
 TMapFile.h:98
 TMapFile.h:99
 TMapFile.h:100
 TMapFile.h:101
 TMapFile.h:102
 TMapFile.h:103
 TMapFile.h:104
 TMapFile.h:105
 TMapFile.h:106
 TMapFile.h:107
 TMapFile.h:108
 TMapFile.h:109
 TMapFile.h:110
 TMapFile.h:111
 TMapFile.h:112
 TMapFile.h:113
 TMapFile.h:114
 TMapFile.h:115
 TMapFile.h:116
 TMapFile.h:117
 TMapFile.h:118
 TMapFile.h:119
 TMapFile.h:120
 TMapFile.h:121
 TMapFile.h:122
 TMapFile.h:123
 TMapFile.h:124
 TMapFile.h:125
 TMapFile.h:126
 TMapFile.h:127
 TMapFile.h:128
 TMapFile.h:129
 TMapFile.h:130
 TMapFile.h:131
 TMapFile.h:132
 TMapFile.h:133
 TMapFile.h:134
 TMapFile.h:135
 TMapFile.h:136
 TMapFile.h:137
 TMapFile.h:138
 TMapFile.h:139
 TMapFile.h:140
 TMapFile.h:141
 TMapFile.h:142
 TMapFile.h:143
 TMapFile.h:144
 TMapFile.h:145
 TMapFile.h:146
 TMapFile.h:147
 TMapFile.h:148
 TMapFile.h:149
 TMapFile.h:150
 TMapFile.h:151
 TMapFile.h:152
 TMapFile.h:153
 TMapFile.h:154
 TMapFile.h:155
 TMapFile.h:156
 TMapFile.h:157
 TMapFile.h:158
 TMapFile.h:159
 TMapFile.h:160
 TMapFile.h:161
 TMapFile.h:162
 TMapFile.h:163
 TMapFile.h:164
 TMapFile.h:165
 TMapFile.h:166
 TMapFile.h:167
 TMapFile.h:168
 TMapFile.h:169
 TMapFile.h:170
 TMapFile.h:171
 TMapFile.h:172
 TMapFile.h:173
 TMapFile.h:174
 TMapFile.h:175
 TMapFile.h:176
 TMapFile.h:177
 TMapFile.h:178
 TMapFile.h:179
 TMapFile.h:180
 TMapFile.h:181
 TMapFile.h:182
 TMapFile.h:183
 TMapFile.h:184
 TMapFile.h:185
 TMapFile.h:186
 TMapFile.h:187
 TMapFile.h:188
 TMapFile.h:189
 TMapFile.h:190
 TMapFile.h:191
 TMapFile.h:192
 TMapFile.h:193
 TMapFile.h:194
 TMapFile.h:195
 TMapFile.h:196
 TMapFile.h:197
 TMapFile.h:198
 TMapFile.h:199
 TMapFile.h:200
 TMapFile.h:201
 TMapFile.h:202
 TMapFile.h:203
 TMapFile.h:204
 TMapFile.h:205
 TMapFile.h:206
 TMapFile.h:207
 TMapFile.h:208
 TMapFile.h:209
 TMapFile.h:210
 TMapFile.h:211