1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef _MORKHANDLE_ 7 #define _MORKHANDLE_ 1 8 9 #ifndef _MORK_ 10 # include "mork.h" 11 #endif 12 13 #ifndef _MORKNODE_ 14 # include "morkNode.h" 15 #endif 16 17 #ifndef _MORKDEQUE_ 18 # include "morkDeque.h" 19 #endif 20 21 #ifndef _MORKPOOL_ 22 # include "morkPool.h" 23 #endif 24 25 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 26 27 class morkPool; 28 class morkObject; 29 class morkFactory; 30 31 #define morkDerived_kHandle /*i*/ 0x486E /* ascii 'Hn' */ 32 #define morkHandle_kTag 0x68416E44 /* ascii 'hAnD' */ 33 34 /*| morkHandle: 35 |*/ 36 class morkHandle : public morkNode { 37 // public: // slots inherited from morkNode (meant to inform only) 38 // nsIMdbHeap* mNode_Heap; 39 40 // mork_base mNode_Base; // must equal morkBase_kNode 41 // mork_derived mNode_Derived; // depends on specific node subclass 42 43 // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead 44 // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone 45 // mork_able mNode_Mutable; // can this node be modified? 46 // mork_load mNode_Load; // is this node clean or dirty? 47 48 // mork_uses mNode_Uses; // refcount for strong refs 49 // mork_refs mNode_Refs; // refcount for strong refs + weak refs 50 51 public: // state is public because the entire Mork system is private 52 mork_u4 mHandle_Tag; // must equal morkHandle_kTag 53 morkEnv* mHandle_Env; // pool that allocated this handle 54 morkHandleFace* mHandle_Face; // cookie from pool containing this 55 morkObject* mHandle_Object; // object this handle wraps for MDB API 56 mork_magic mHandle_Magic; // magic sig different in each subclass 57 58 // { ===== begin morkNode interface ===== 59 public: // morkNode virtual methods 60 virtual void CloseMorkNode( 61 morkEnv* ev) override; // CloseHandle() only if open 62 virtual ~morkHandle(); // assert that CloseHandle() executed earlier 63 64 public: // morkHandle construction & destruction 65 morkHandle( 66 morkEnv* ev, // note morkUsage is always morkUsage_kPool 67 morkHandleFace* ioFace, // must not be nil, cookie for this handle 68 morkObject* ioObject, // must not be nil, the object for this handle 69 mork_magic inMagic); // magic sig to denote specific subclass 70 void CloseHandle(morkEnv* ev); // called by CloseMorkNode(); 71 72 private: // copying is not allowed 73 morkHandle(const morkHandle& other); 74 morkHandle& operator=(const morkHandle& other); 75 76 protected: // special case empty construction for morkHandleFrame 77 friend class morkHandleFrame; morkHandle()78 morkHandle() {} 79 80 public: // dynamic type identification IsHandle()81 mork_bool IsHandle() const { 82 return IsNode() && mNode_Derived == morkDerived_kHandle; 83 } 84 // } ===== end morkNode methods ===== 85 86 public: // morkHandle memory management operators new(size_t inSize,morkPool & ioPool,morkZone & ioZone,morkEnv * ev)87 void* operator new(size_t inSize, morkPool& ioPool, morkZone& ioZone, 88 morkEnv* ev) noexcept(true) { 89 return ioPool.NewHandle(ev, inSize, &ioZone); 90 } 91 new(size_t inSize,morkPool & ioPool,morkEnv * ev)92 void* operator new(size_t inSize, morkPool& ioPool, 93 morkEnv* ev) noexcept(true) { 94 return ioPool.NewHandle(ev, inSize, (morkZone*)0); 95 } 96 new(size_t inSize,morkHandleFace * ioFace)97 void* operator new(size_t inSize, morkHandleFace* ioFace) noexcept(true) { 98 MORK_USED_1(inSize); 99 return ioFace; 100 } 101 102 public: // other handle methods GoodHandleTag()103 mork_bool GoodHandleTag() const { return mHandle_Tag == morkHandle_kTag; } 104 105 void NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const; 106 void NewDownHandleError(morkEnv* ev) const; 107 void NilFactoryError(morkEnv* ev) const; 108 void NilHandleObjectError(morkEnv* ev) const; 109 void NonNodeObjectError(morkEnv* ev) const; 110 void NonOpenObjectError(morkEnv* ev) const; 111 112 morkObject* GetGoodHandleObject(morkEnv* ev, mork_bool inMutable, 113 mork_magic inMagicType, 114 mork_bool inClosedOkay) const; 115 116 public: // interface supporting mdbObject methods 117 morkEnv* CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable, 118 mork_bool inClosedOkay, nsresult* outErr) const; 119 120 // { ----- begin mdbObject style methods ----- 121 nsresult Handle_IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly); 122 123 nsresult Handle_GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory); 124 nsresult Handle_GetWeakRefCount(nsIMdbEnv* ev, mdb_count* outCount); 125 nsresult Handle_GetStrongRefCount(nsIMdbEnv* ev, mdb_count* outCount); 126 127 nsresult Handle_AddWeakRef(nsIMdbEnv* ev); 128 nsresult Handle_AddStrongRef(nsIMdbEnv* ev); 129 130 nsresult Handle_CutWeakRef(nsIMdbEnv* ev); 131 nsresult Handle_CutStrongRef(nsIMdbEnv* ev); 132 133 nsresult Handle_CloseMdbObject(nsIMdbEnv* ev); 134 nsresult Handle_IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen); 135 // } ----- end mdbObject style methods ----- 136 137 public: // typesafe refcounting inlines calling inherited morkNode methods SlotWeakHandle(morkHandle * me,morkEnv * ev,morkHandle ** ioSlot)138 static void SlotWeakHandle(morkHandle* me, morkEnv* ev, morkHandle** ioSlot) { 139 morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot); 140 } 141 SlotStrongHandle(morkHandle * me,morkEnv * ev,morkHandle ** ioSlot)142 static void SlotStrongHandle(morkHandle* me, morkEnv* ev, 143 morkHandle** ioSlot) { 144 morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot); 145 } 146 }; 147 148 #define morkHandleFrame_kPadSlotCount 4 149 150 /*| morkHandleFrame: an object format used for allocating and maintaining 151 **| instances of morkHandle, with leading slots used to maintain this in a 152 **| linked list, and following slots to provide extra footprint that might 153 **| be needed by any morkHandle subclasses that include very little extra 154 **| space (by virtue of the fact that each morkHandle subclass is expected 155 **| to multiply inherit from another base class that has only abstract methods 156 **| for space overhead related only to some vtable representation). 157 |*/ 158 class morkHandleFrame { 159 public: 160 morkLink mHandleFrame_Link; // list storage without trampling Handle 161 morkHandle mHandleFrame_Handle; 162 mork_ip mHandleFrame_Padding[morkHandleFrame_kPadSlotCount]; 163 164 public: AsHandle()165 morkHandle* AsHandle() { return &mHandleFrame_Handle; } 166 morkHandleFrame()167 morkHandleFrame() {} // actually, morkHandleFrame never gets constructed 168 169 private: // copying is not allowed 170 morkHandleFrame(const morkHandleFrame& other); 171 morkHandleFrame& operator=(const morkHandleFrame& other); 172 }; 173 174 #define morkHandleFrame_kHandleOffset \ 175 mork_OffsetOf(morkHandleFrame, mHandleFrame_Handle) 176 177 #define morkHandle_AsHandleFrame(h) \ 178 ((h)->mHandle_Block, \ 179 ((morkHandleFrame*)(((mork_u1*)(h)) - morkHandleFrame_kHandleOffset))) 180 181 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 182 183 #endif /* _MORKHANDLE_ */ 184