// =====================================================================
/*!
//
//  \file TObjectSharedMemory.hh
//  \brief This file contains the TObjectSharedMemory class.
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: TObjectSharedMemory.hh,v 1.7 2004/03/07 16:51:40 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TObjectSharedMemory.hh,v $
//  Revision 1.7  2004/03/07 16:51:40  goiwai
//  rootcintでshmid_dsを認識しないので、その対策です。
//
//  Revision 1.6  2004/03/07 10:30:32  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.5  2004/01/19 21:09:41  goiwai
//  プリプロセッサの接頭辞をCLDAQ__に変更しました.
//
//  Revision 1.4  2003/11/03 08:35:13  goiwai
//  Doxygen用のタグとコメントをうちこんでいく試みを開始しました.
//
//  Revision 1.3  2003/10/06 17:02:42  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:19:31  goiwai
//  ファイルにコミットログをつけることにしました.
//
*/
// =====================================================================
#ifndef CLDAQ__TOBJECTSHAREDMEMORY_HH
#define CLDAQ__TOBJECTSHAREDMEMORY_HH

#include "Tglobals.h"

//OutputしてるときはInputさせない

/*!
// \example
//
// If example code exists.
//
*/

/*!
// \class TObjectSharedMemory
// \brief This is the TObjectSharedMemory class.
// \author Go IWAI <goiwai@users.sourceforge.jp>
//
// The TObjectSharedMemory class detail description.
// Write it down ASAP!
//
// \todo None?
// \bug None?
// \ingroup PersistencyCategory
*/
#ifdef __CLDAQ_ROOT_DLL
#ifndef _SYS_SHM_H
// from <bit/shm.h>, for rootcint
typedef struct {
    struct ipc_perm shm_perm;  /* operation perms */
    int shm_segsz;             /* size of segment (bytes) */
    time_t shm_atime;          /* last attach time */
    time_t shm_dtime;          /* last detach time */
    time_t shm_ctime;          /* last change time */
    unsigned short shm_cpid;   /* pid of creator */
    unsigned short shm_lpid;   /* pid of last operator */
    short shm_nattch;          /* no. of current attaches */
} shmid_ds;
#endif
#endif

class TObjectSharedMemory
{

  protected:
    static TObjectSharedMemory* theObjectSharedMemory;

  public:
    enum { tDefaultMaxEvent = 100 };
    enum { tDefaultMemorySize = 1024 * 1024 };
    
  protected:
    Tint theSharedMemoryID;
    Tint theMemorySize;
    Tint theMaxEvent;
    Tint theCurrentPositionOfMemorySpace;
    Tbool* theReadable;
    Tvoid* theBaseAddress;
    Tvoid* theAddress;

  public:
    TObjectSharedMemory( Tint memsize, Tint maxevt );

  protected:
    virtual ~TObjectSharedMemory();

  public:
    Tvoid* Attach( const Tvoid* shmaddr = 0, Tint shmflg = 0 ) const;
    Tint Detach();
    Tint Remove( struct shmid_ds* buf = 0 );

  public:
    Tint GetSharedMemoryID() const;
    Tint GetMemorySize() const;
    Tvoid* GetBaseAddress() const;
    Tvoid* GetAddress() const;
    Tint GetMaxEvent() const;
    Tint GetCurrentPositionOfMemorySpace() const;
    Tvoid SetMaxEvent( Tint maxevt );
    Tvoid SetCurrentPositionOfMemorySpace( Tint pos );
    Tvoid SetSharedMemoryID( Tint memid );
    Tvoid SetMemorySize( Tint memsize );
    Tvoid SetAddress( Tvoid* shmaddr );
    Tbool IsReadable() const;
    Tvoid SetReadable( Tbool permission );

  public:
    static TObjectSharedMemory* GetObjectSharedMemory();

#ifdef __CLDAQ_ROOT_DLL
    ClassDef(TObjectSharedMemory,0)
#endif

};

inline TObjectSharedMemory* TObjectSharedMemory::GetObjectSharedMemory()
{
  return theObjectSharedMemory;
}

inline Tint TObjectSharedMemory::GetMaxEvent() const
{
  return theMaxEvent;
}

inline Tint TObjectSharedMemory::GetCurrentPositionOfMemorySpace() const
{
  return theCurrentPositionOfMemorySpace;
}

inline Tvoid TObjectSharedMemory::SetMaxEvent( Tint maxevt )
{
  theMaxEvent = maxevt;
  return;
}

inline Tvoid TObjectSharedMemory::SetCurrentPositionOfMemorySpace( Tint pos )
{
  theCurrentPositionOfMemorySpace = pos;
  return;
}

inline Tint TObjectSharedMemory::GetSharedMemoryID() const
{
  return theSharedMemoryID;
}

inline Tint TObjectSharedMemory::GetMemorySize() const
{
  return theMemorySize;
}

inline Tvoid* TObjectSharedMemory::GetBaseAddress() const
{
  return theBaseAddress;
}

inline Tvoid* TObjectSharedMemory::GetAddress() const
{
  return theAddress;
}

inline Tvoid TObjectSharedMemory::SetSharedMemoryID( Tint memid )
{
  theSharedMemoryID = memid;
  return;
}

inline Tvoid TObjectSharedMemory::SetMemorySize( Tint memsize )
{
  theMemorySize = memsize;
  return;
}

inline Tvoid TObjectSharedMemory::SetAddress( Tvoid* shmaddr )
{
  theAddress = shmaddr;
  return;
}

inline Tvoid* TObjectSharedMemory::Attach( const Tvoid* shmaddr, Tint shmflg ) const
{
  return shmat( theSharedMemoryID, shmaddr, shmflg );
}

inline Tint TObjectSharedMemory::Detach()
{
  return shmdt( (Tvoid*)theReadable );
}

inline Tint TObjectSharedMemory::Remove( struct shmid_ds* buf )
{
  return shmctl( theSharedMemoryID, IPC_RMID, buf );
}

inline Tbool TObjectSharedMemory::IsReadable() const
{
  return *theReadable;
}

inline Tvoid TObjectSharedMemory::SetReadable( Tbool permission )
{
  *theReadable = permission;
  return;
}

#endif
