core/systems/HandleSys.h
author David Anderson <dvander@alliedmods.net>
Mon Jan 01 19:50:16 2007 +0000 (2007-01-01)
changeset 252 ce166c465bad
parent 229 7819a42069e4
child 259 ca9b124a2544
permissions -rw-r--r--
added usage of the Handle System to begin experimenting
     1 #ifndef _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
     2 #define _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
     3 
     4 #include <IHandleSys.h>
     5 #include "sm_globals.h"
     6 #include "sm_trie.h"
     7 #include "sourcemod.h"
     8 #include "sm_memtable.h"
     9 
    10 #define HANDLESYS_MAX_HANDLES		(1<<14)
    11 #define HANDLESYS_MAX_TYPES			(1<<9)
    12 #define HANDLESYS_MAX_SUBTYPES		0xF
    13 #define HANDLESYS_SUBTYPE_MASK		0xF
    14 #define HANDLESYS_TYPEARRAY_SIZE	(HANDLESYS_MAX_TYPES * (HANDLESYS_MAX_SUBTYPES + 1))
    15 #define HANDLESYS_MAX_SERIALS		0xFFFF
    16 #define HANDLESYS_SERIAL_MASK		0xFFFF0000
    17 #define HANDLESYS_HANDLE_MASK		0x0000FFFF
    18 
    19 /**
    20  *   The QHandle is a nasty structure that compacts the handle system into a big vector.
    21  * The members of the vector each encapsulate one Handle, however, they also act as nodes
    22  * in an inlined linked list and an inlined vector.
    23  *
    24  *   The first of these lists is the 'freeID' list.  Each node from 1 to N (where N
    25  * is the number of free nodes) has a 'freeID' that specifies a free Handle ID.  This
    26  * is a quick hack to get around allocating a second base vector.
    27  *
    28  *   The second vector is the identity linked list.  An identity has its own handle, so
    29  * these handles are used as sentinel nodes for index linking.  They point to the first and last
    30  * index into the handle array.  Each subsequent Handle who is owned by that indentity is mapped into
    31  * that list.  This lets owning identities be unloaded in O(n) time.
    32  *
    33  *   Eventually, there may be a third list for type chains.
    34  */
    35 
    36 enum HandleSet
    37 {
    38 	HandleSet_None = 0,
    39 	HandleSet_Used,
    40 	HandleSet_Identity
    41 };
    42 
    43 struct QHandle
    44 {
    45 	HandleType_t type;			/* Handle type */
    46 	void *object;				/* Unmaintained object pointer */
    47 	IdentityToken_t *owner;		/* Identity of object which owns this */
    48 	unsigned int serial;		/* Serial no. for sanity checking */
    49 	unsigned int refcount;		/* Reference count for safe destruction */
    50 	Handle_t clone;				/* If non-zero, this is our cloned parent */
    51 	HandleSet set;				/* Information about the handle's state */
    52 	/* The following variables are unrelated to the Handle array, and used 
    53 	 * as an inlined chain of information */
    54 	unsigned int freeID;		/* ID of a free handle in the free handle chain */
    55 	/* Indexes into the handle array for owner membership.
    56 	 * For identity roots, these are treated as the head/tail. */
    57 	unsigned int ch_prev;		/* chained previous handle or HEAD */
    58 	unsigned int ch_next;		/* chained next handle or TAIL */
    59 };
    60 
    61 struct QHandleType
    62 {
    63 	IHandleTypeDispatch *dispatch;
    64 	unsigned int freeID;
    65 	unsigned int children;
    66 	HandleSecurity sec;
    67 	unsigned int opened;
    68 	int nameIdx;
    69 };
    70 
    71 class HandleSystem : 
    72 	public IHandleSys
    73 {
    74 	friend HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index);
    75 	friend class ShareSystem;
    76 public:
    77 	HandleSystem();
    78 	~HandleSystem();
    79 public: //IHandleSystem
    80 	HandleType_t CreateType(const char *name, IHandleTypeDispatch *dispatch);
    81 	HandleType_t CreateTypeEx(const char *name,	
    82 							  IHandleTypeDispatch *dispatch, 
    83 							  HandleType_t parent, 
    84 							  const HandleSecurity *security,
    85 							  IdentityToken_t *ident);
    86 	HandleType_t CreateChildType(const char *name, HandleType_t parent, IHandleTypeDispatch *dispatch);
    87 	bool RemoveType(HandleType_t type, IdentityToken_t *ident);
    88 	bool FindHandleType(const char *name, HandleType_t *type);
    89 	Handle_t CreateHandle(HandleType_t type, 
    90 							void *object, 
    91 							IdentityToken_t *source, 
    92 							IdentityToken_t *ident);
    93 	Handle_t CreateScriptHandle(HandleType_t type, void *object, IPluginContext *pContext, IdentityToken_t *ident);
    94 	HandleError FreeHandle(Handle_t handle, IdentityToken_t *ident);
    95 	HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *source, IdentityToken_t *ident);
    96 	HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object);
    97 	bool TypeCheck(HandleType_t intype, HandleType_t outtype);
    98 protected:
    99 	/**
   100 	 * Decodes a handle with sanity and security checking.
   101 	 */
   102 	HandleError GetHandle(Handle_t handle, 
   103 						  IdentityToken_t *ident, 
   104 						  QHandle **pHandle, 
   105 						  unsigned int *index,
   106 						  HandleAccessRight access);
   107 
   108 	/**
   109 	 * Creates a basic handle and sets its reference count to 1.
   110 	 * Does not do any type or security checking.
   111 	 */
   112 	HandleError MakePrimHandle(HandleType_t type, 
   113 							   QHandle **pHandle, 
   114 							   unsigned int *index, 
   115 							   HandleType_t *handle,
   116 							   IdentityToken_t *owner);
   117 
   118 	/**
   119 	 * Frees a primitive handle.  Does no object freeing, only reference count, bookkeepping, 
   120 	 * and linked list maintenance.
   121 	 */
   122 	void ReleasePrimHandle(unsigned int index);
   123 
   124 	/**
   125 	 * Sets the security owner of a type
   126 	 */
   127 	void SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken);
   128 
   129 	/** 
   130 	 * Marks a handle as an identity.
   131 	 * This prevents it from being tampered with by outside stuff
   132 	 */
   133 	void MarkHandleAsIdentity(Handle_t handle);
   134 private:
   135 	QHandle *m_Handles;
   136 	QHandleType *m_Types;
   137 	Trie *m_TypeLookup;
   138 	unsigned int m_TypeTail;
   139 	unsigned int m_FreeTypes;
   140 	unsigned int m_HandleTail;
   141 	unsigned int m_FreeHandles;
   142 	unsigned int m_HSerial;
   143 	BaseStringTable *m_strtab;
   144 };
   145 
   146 extern HandleSystem g_HandleSys;
   147 
   148 #endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_