#ifndef __CRefTable_h__
#define __CRefTable_h__ 1
#include "DirServicesTypes.h"
#include "PrivateTypes.h"
#include "DSMutexSemaphore.h"
#include <CoreFoundation/CoreFoundation.h>
#include <map>
#include <set>
class CRefTable;
class CServerPlugin;
extern DSMutexSemaphore *gTableMutex;
extern CRefTable *gRefTable;
#define kMaxTableItems 512
#define kMaxTables 0xFF
typedef struct sListInfo *sListInfoPtr;
typedef struct sListInfo {
uInt32 fRefNum;
uInt32 fType;
sInt32 fPID;
uInt32 fIPAddress;
sListInfoPtr fNext;
} sListInfo;
typedef struct sPIDInfo {
sInt32 fPID;
uInt32 fIPAddress;
sPIDInfo *fNext;
} sPIDInfo;
typedef struct sRefEntry {
uInt32 fRefNum;
uInt32 fType;
uInt32 fParentID;
sInt32 fPID;
uInt32 fIPAddress;
CServerPlugin *fPlugin;
sListInfo *fChildren;
sPIDInfo *fChildPID;
} sRefEntry;
typedef struct sRefCleanUpEntry {
uInt32 fRefNum;
uInt32 fType;
CServerPlugin *fPlugin;
sRefCleanUpEntry *fNext;
} sRefCleanUpEntry;
typedef sInt32 RefDeallocateProc ( uInt32 inRefNum, uInt32 inRefType, CServerPlugin *inPluginPtr );
typedef struct sRefTable *sRefTablePtr;
typedef struct sRefTable {
uInt32 fTableNum;
uInt32 fCurRefNum;
uInt32 fItemCnt;
sRefEntry *fTableData[ kMaxTableItems ];
} sRefTable;
typedef std::set<uInt32> tDirRefSet;
typedef std::map<uInt32, tDirRefSet> tPIDDirRefMap;
typedef std::map<uInt32, tPIDDirRefMap> tIPPIDDirRefMap;
typedef std::map<uInt32, uInt32> tPIDRefCountMap;
typedef std::map<uInt32, tPIDRefCountMap> tIPPIDRefCountMap;
class CRefTable {
public:
CRefTable ( RefDeallocateProc *deallocProc );
virtual ~CRefTable ( void );
void Lock ( void );
void Unlock ( void );
static tDirStatus VerifyDirRef ( tDirReference inDirRef, CServerPlugin **outPlugin, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus VerifyNodeRef ( tDirNodeReference inDirNodeRef, CServerPlugin **outPlugin, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus VerifyRecordRef ( tRecordReference inRecordRef, CServerPlugin **outPlugin, sInt32 inPID, uInt32 inIPAddress, bool inDaemonPID_OK = false );
static tDirStatus VerifyAttrListRef ( tAttributeListRef inAttributeListRef, CServerPlugin **outPlugin, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus VerifyAttrValueRef ( tAttributeValueListRef inAttributeValueListRef, CServerPlugin **outPlugin, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus NewDirRef ( uInt32 *outNewRef, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus NewNodeRef ( uInt32 *outNewRef, CServerPlugin *inPlugin, uInt32 inParentID, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus NewRecordRef ( uInt32 *outNewRef, CServerPlugin *inPlugin, uInt32 inParentID, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus NewAttrListRef ( uInt32 *outNewRef, CServerPlugin *inPlugin, uInt32 inParentID, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus NewAttrValueRef ( uInt32 *outNewRef, CServerPlugin *inPlugin, uInt32 inParentID, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus RemoveDirRef ( uInt32 inDirRef, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus RemoveNodeRef ( uInt32 inNodeRef, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus RemoveRecordRef ( uInt32 inRecRef, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus RemoveAttrListRef ( uInt32 inAttrListRef, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus RemoveAttrValueRef ( uInt32 InAttrValueRef, sInt32 inPID, uInt32 inIPAddress );
static tDirStatus SetNodePluginPtr ( tDirNodeReference inNodeRef, CServerPlugin *inPlugin );
static tDirStatus AddChildPIDToRef ( uInt32 inRefNum, uInt32 inParentPID, sInt32 inChildPID, uInt32 inIPAddress );
static void CleanClientRefs ( uInt32 inIPAddress, uInt32 inPIDorPort );
private:
tDirStatus VerifyReference ( tDirReference inDirRef, uInt32 inType, CServerPlugin **outPlugin, sInt32 inPID, uInt32 inIPAddress, bool inDaemonPID_OK = false );
tDirStatus GetNewRef ( uInt32 *outRef, uInt32 inParentID, eRefTypes inType, CServerPlugin *inPlugin, sInt32 inPID, uInt32 inIPAddress );
tDirStatus RemoveRef ( uInt32 inRefNum, uInt32 inType, sInt32 inPID, uInt32 inIPAddress, bool inbAtTop = false);
tDirStatus SetPluginPtr ( uInt32 inRefNum, uInt32 inType, CServerPlugin *inPlugin );
tDirStatus GetReference ( uInt32 inRefNum, sRefEntry **outRefData );
tDirStatus LinkToParent ( uInt32 inRefNum, uInt32 inType, uInt32 inParentID, sInt32 inPID, uInt32 inIPAddress );
tDirStatus UnlinkFromParent ( uInt32 inRefNum );
void RemoveChildren ( sListInfo *inChildList, sInt32 inPID, uInt32 inIPAddress );
sRefTable* GetNextTable ( sRefTable *inCurTable );
sRefTable* GetThisTable ( uInt32 inTableNum );
sRefEntry* GetTableRef ( uInt32 inRefNum );
uInt32 UpdateClientPIDRefCount
( sInt32 inClientPID, uInt32 inIPAddress, bool inUpRefCount, uInt32 inDirRef=0 );
void DoCleanClientRefs ( uInt32 inIPAddress, uInt32 inPIDorPort );
uInt32 fTableCount;
sRefTable *fRefTables[ kMaxTables + 1 ]; RefDeallocateProc *fDeallocProc;
tIPPIDDirRefMap fClientDirRefMap;
tIPPIDRefCountMap fClientRefCountMap;
DSMutexSemaphore *fClientPIDListLock; DSMutexSemaphore fTableMutex;
sRefCleanUpEntry *fRefCleanUpEntriesHead;
sRefCleanUpEntry *fRefCleanUpEntriesTail;
};
#endif