blob: f8e18007e63f5a84cef72c9e0b0b22ec9e658a5f [file]
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
/*++
Module Name:
shmobject.hpp
Abstract:
Shared memory based object
--*/
#ifndef _PAL_SHMOBJECT_HPP
#define _PAL_SHMOBJECT_HPP
#include "palobjbase.hpp"
#include "pal/shm.hpp"
extern "C"
{
#include "pal/list.h"
}
namespace CorUnix
{
class CSimpleSharedMemoryLock : public IDataLock
{
public:
void
AcquireLock(
CPalThread *pthr,
IDataLock **ppDataLock
)
{
SHMLock();
*ppDataLock = static_cast<IDataLock*>(this);
};
virtual
void
ReleaseLock(
CPalThread *pthr,
bool fDataChanged
)
{
SHMRelease();
};
};
typedef struct _SHMObjData
{
SHMPTR shmPrevObj;
SHMPTR shmNextObj;
BOOL fAddedToList;
SHMPTR shmObjName;
SHMPTR shmObjImmutableData;
SHMPTR shmObjSharedData;
LONG lProcessRefCount;
DWORD dwNameLength;
PalObjectTypeId eTypeId;
PVOID pvSynchData;
} SHMObjData;
class CSharedMemoryObject : public CPalObjectBase
{
template <class T> friend void InternalDelete(T *p);
protected:
//
// Entry on the process's named or anonymous object list
//
LIST_ENTRY m_le;
//
// The lock that guards access to that list
//
CRITICAL_SECTION *m_pcsObjListLock;
//
// The SHMObjData for this object, protected by the
// shared memory lock.
//
SHMPTR m_shmod;
//
// The shared data (i.e., m_shmObjData->shmObjSharedData)
// for this object, mapped into this process. This will be
// NULL if m_pot->dwSharedDataSize is 0. Access to this data
// is controlled by m_ssmlSharedData when m_ObjectDomain is
// SharedObject, and m_sdlSharedData when it is ProcessLocalObject.
//
VOID *m_pvSharedData;
CSimpleSharedMemoryLock m_ssmlSharedData;
CSimpleDataLock m_sdlSharedData;
//
// Is this object process local or shared?
//
ObjectDomain m_ObjectDomain;
//
// m_fSharedDataDereferenced will be TRUE if DereferenceSharedData
// has already been called. (N.B. -- this is a LONG instead of a bool
// because it is passed to InterlockedExchange). If the shared data blob
// should be freed in the object's destructor (i.e., SHMfree should be
// called on the appropriate SHMPTRs) DereferenceSharedData will
// set m_fDeleteSharedData to TRUE.
//
LONG m_fSharedDataDereferenced;
LONG m_fDeleteSharedData;
PAL_ERROR
AllocateSharedDataItems(
SHMPTR *pshmObjData,
SHMObjData **ppsmod
);
static
void
FreeSharedDataAreas(
SHMPTR shmObjData
);
void
PromoteSharedData(
SHMPTR shmObjData,
SHMObjData *psmod
);
bool
DereferenceSharedData();
virtual
void
AcquireObjectDestructionLock(
CPalThread *pthr
);
virtual
bool
ReleaseObjectDestructionLock(
CPalThread *pthr,
bool fDestructionPending
);
virtual ~CSharedMemoryObject();
public:
//
// Constructor used for new object
//
CSharedMemoryObject(
CObjectType *pot,
CRITICAL_SECTION *pcsObjListLock
)
:
CPalObjectBase(pot),
m_pcsObjListLock(pcsObjListLock),
m_shmod(SHMNULL),
m_pvSharedData(NULL),
m_ObjectDomain(ProcessLocalObject),
m_fSharedDataDereferenced(FALSE),
m_fDeleteSharedData(FALSE)
{
InitializeListHead(&m_le);
};
//
// Constructor used to import a shared object into this process. The
// shared memory lock must be held when calling this contstructor
//
CSharedMemoryObject(
CObjectType *pot,
CRITICAL_SECTION *pcsObjListLock,
SHMPTR shmSharedObjectData,
SHMObjData *psmod,
bool fAddRefSharedData
)
:
CPalObjectBase(pot),
m_pcsObjListLock(pcsObjListLock),
m_shmod(shmSharedObjectData),
m_pvSharedData(NULL),
m_ObjectDomain(SharedObject),
m_fSharedDataDereferenced(FALSE),
m_fDeleteSharedData(FALSE)
{
InitializeListHead(&m_le);
if (fAddRefSharedData)
{
psmod->lProcessRefCount += 1;
}
};
virtual
PAL_ERROR
Initialize(
CPalThread *pthr,
CObjectAttributes *poa
);
virtual
PAL_ERROR
InitializeFromExistingSharedData(
CPalThread *pthr,
CObjectAttributes *poa
);
virtual
PAL_ERROR
EnsureObjectIsShared(
CPalThread *pthr
);
void
CleanupForProcessShutdown(
CPalThread *pthr
);
SHMPTR
GetShmObjData(
void
)
{
return m_shmod;
};
PLIST_ENTRY
GetObjectListLink(
void
)
{
return &m_le;
}
//
// Clients of this object -- in particular, CSharedMemoryObjectManager
// -- can't use CONTAINING_RECORD directly, since they don't have
// access to m_Link.
//
static
CSharedMemoryObject*
GetObjectFromListLink(PLIST_ENTRY pLink);
//
// IPalObject routines
//
virtual
PAL_ERROR
GetSharedData(
CPalThread *pthr,
LockType eLockRequest,
IDataLock **ppDataLock,
void **ppvSharedData
);
virtual
PAL_ERROR
GetSynchStateController(
CPalThread *pthr,
ISynchStateController **ppStateController
);
virtual
PAL_ERROR
GetSynchWaitController(
CPalThread *pthr,
ISynchWaitController **ppWaitController
);
virtual
ObjectDomain
GetObjectDomain(
void
);
virtual
PAL_ERROR
GetObjectSynchData(
VOID **ppvSynchData
);
};
class CSharedMemoryWaitableObject : public CSharedMemoryObject
{
template <class T> friend void InternalDelete(T *p);
protected:
VOID *m_pvSynchData;
virtual ~CSharedMemoryWaitableObject();
public:
CSharedMemoryWaitableObject(
CObjectType *pot,
CRITICAL_SECTION *pcsObjListLock
)
:
CSharedMemoryObject(pot, pcsObjListLock),
m_pvSynchData(NULL)
{
};
//
// Constructor used to import a shared object into this process. The
// shared memory lock must be held when calling this contstructor
//
CSharedMemoryWaitableObject(
CObjectType *pot,
CRITICAL_SECTION *pcsObjListLock,
SHMPTR shmSharedObjectData,
SHMObjData *psmod,
bool fAddRefSharedData
)
:
CSharedMemoryObject(pot, pcsObjListLock, shmSharedObjectData, psmod, fAddRefSharedData),
m_pvSynchData(psmod->pvSynchData)
{
};
virtual
PAL_ERROR
Initialize(
CPalThread *pthr,
CObjectAttributes *poa
);
virtual
PAL_ERROR
EnsureObjectIsShared(
CPalThread *pthr
);
//
// IPalObject routines
//
virtual
PAL_ERROR
GetSynchStateController(
CPalThread *pthr,
ISynchStateController **ppStateController
);
virtual
PAL_ERROR
GetSynchWaitController(
CPalThread *pthr,
ISynchWaitController **ppWaitController
);
virtual
PAL_ERROR
GetObjectSynchData(
VOID **ppvSynchData
);
};
}
#endif // _PAL_SHMOBJECT_HPP