add HLH_Ref
[HLH_utils.git] / HLH_Ref.h
blob1f938203961cc68a6ef98fa1f4a3d5bc20399690
1 /*******************************************************************************
2 * File : HLH_Ref.h
3 *
4 * Author : Henry He
5 * Created : Wed 18 Nov 2009 03:59:55 PM CST
6 * Description :
7 ******************************************************************************/
9 #ifndef __HLH_REF_INC_20091118_155955_HENRY__
10 #define __HLH_REF_INC_20091118_155955_HENRY__
13 /*******************************************************************************
14 * Desc : Includes Files
15 ******************************************************************************/
18 /*******************************************************************************
19 * Desc : Macro Definations
20 ******************************************************************************/
21 #define HLH_REF_ERR_FAILED (-1)
22 #define HLH_REF_ERR_ALREADY_REFERED (-2)
23 #define HLH_REF_ERR_NOT_REFERED (-3)
24 #define HLH_REF_ERR_CANNT_REFER (-4)
27 /*******************************************************************************
28 * Desc : Type Definations
29 ******************************************************************************/
32 /*******************************************************************************
33 * Desc : Global Variables
34 ******************************************************************************/
37 /*******************************************************************************
38 * Desc : Functions
39 ******************************************************************************/
43 /******************************************************************************
44 * Class : HLH_Ref
45 * Desc :
46 ******************************************************************************/
47 template <class T>
48 class HLH_Ref
51 public:
53 //===================== TYPEDEFS =============================================
55 // Type of release function
56 typedef void (*ReleaseThisFunc) (T *pvThis);
57 typedef void (*ReleaseOtherFunc) (T *pvThis, void *pvOther);
58 typedef enum RefType {REF_TYPE_NEW, REF_TYPE_THIS, REF_TYPE_OTHER}
60 // ==================== LIFECYCLE =========================================
62 // Constructor of HLH_Ref: refer to HLH_Ref
63 HLH_Ref (const HLH_Ref &zhrRef, UINT32 unRef = 1) {
64 Ref (zhrRef, unRef);
67 // Constructor of HLH_Ref: refer to a pointer created by new method
68 explicit HLH_Ref (T *ptObj = NULL, UINT32 unRef = 1) {
69 RefNew (ptObj, unRef);
72 // Constructor of HLH_Ref: refer to a pointer created by free method
73 explicit HLH_Ref (T *ptObj = NULL, ReleaseThisFunc zrtRelease = free,
74 bool bDeconstruct = true, UINT32 unRef = 1) {
75 RefThis (ptObj, zrtRelease, bDeconstruct, unRef);
78 // Constructor of HLH_Ref: refer to a pointer that takes this point and
79 // other pointer to release it
80 explicit HLH_Ref (T *ptObj = NULL, ReleaseOtherFunc zroRelease = NULL,
81 void *pvOther = NULL, bool bDeconstruct = false, pvUINT32 unRef = 1) {
82 RefOther (ptObj, rfRelease, bDeconstruct, unRef);
85 // Decontructor of HLH_Ref
86 ~ HLH_Ref () { Destroy (); }
89 public:
91 // ==================== OPERATORS =========================================
93 // Reload of assignment from HLH_Ref
94 HLH_Ref<T> & operator = (const HLH_Ref<T> & zhrRef);
96 // Reload of assignment from pointer of class T
97 HLH_Ref<T> & operator = (T *ptObj);
99 // Reload of address resolve operator
100 T & operator * () const;
102 // Reload of member access operator
103 T * operator -> () const;
107 // ==================== OPERATIONS =========================================
109 // Create a new T class and refer to this new class
110 int New (UINT32 unRef);
112 // Refer to HLH_Ref
113 int Ref (const HLH_Ref &zhrRef, UINT32 unRef = 1);
115 // Refer to a pointer created by new method
116 explicit int RefNew (T *ptObj = NULL, UINT32 unRef = 1);
118 // Refer to a pointer created by free method
119 explicit int RefThis (T *ptObj = NULL, ReleaseThisFunc zrtRelease = free,
120 bool bDeconstruct = true, UINT32 unRef = 1);
122 // Refer to a pointer that takes this point and other pointer to release it
123 explicit int RefOther (T *ptObj = NULL, ReleaseOtherFunc zroRelease = NULL,
124 void *pvOther = NULL, bool bDeconstruct = false, pvUINT32 unRef = 1);
126 // Add reference to this pointer (avoid to use this after all)
127 int AddRef (UINT32 unRef);
129 // Release reference to this pointer (avoid to use this after all)
130 int Release (UINT32 unRef);
132 // Destroy the object refered
133 void Destroy ();
137 // ==================== ACCESS =========================================
139 // Get internal pointer
140 T * Get() const;
142 // Reset the pointer to the initial pointer
143 void Reset(T * p);
147 private:
149 // ==================== OPERATIONS =========================================
152 private:
154 // ==================== MEMBER DATA =========================================
158 // Reference count of this reference
159 UINT32 m_unRef;
161 // Pointer to global reference count
162 UINT32 *m_punRef;
166 // Pointer of this reference
167 T *m_ptObj;
169 // Whether deconstructor should be called
170 bool m_bDeconstruct;
172 // Type of reference
173 RefType m_zrtRefType;
175 // Release functions of REF_TYPE_OTHER type
176 void *m_pvReleaseFunc;
178 // Pointer to the other argument need by release function of REF_TYPE_OTHER type
179 void *m_pvReleaseOther;
182 }; // ----- end of class HLH_Ref -----
188 // ==================== OPERATORS =========================================
192 /******************************************************************************
193 * Func : operator =
194 * Desc : Reload of assignment from HLH_Ref
195 * Args : zhrRef HLH_Ref object assigned from
196 * Outs : return reference of this object
197 ******************************************************************************/
198 HLH_Ref<T> & HLH_Ref::operator = (const HLH_Ref<T> & zhrRef)
200 Ref (zhrRef);
201 return *this;
204 /******************************************************************************
205 * Func : operator =
206 * Desc : Reload of assignment from pointer of class T created by new
207 * Args : ptObj pointer to refer
208 * Outs : return reference of this HLH_Ref
209 ******************************************************************************/
210 HLH_Ref<T> & HLH_Ref::operator = (T *ptObj)
212 RefNew (ptObj);
213 return *this;
216 /******************************************************************************
217 * Func : operator *
218 * Desc : Reload of address resolve operator
219 * Args : NONE
220 * Outs : return reference of this pointer
221 ******************************************************************************/
222 T & HLH_Ref::operator * () const
224 return *m_ptObj;
229 /******************************************************************************
230 * Func : operator ->
231 * Desc : Reload of member access operator
232 * Args : NONE
233 * Outs : return this pointer
234 ******************************************************************************/
235 T * HLH_Ref::operator -> () const
237 return m_ptObj;
243 // ==================== OPERATIONS =========================================
248 /******************************************************************************
249 * Func : HLH_Ref::New
250 * Desc : Create a new T class and refer to this new class
251 * Args : unRef initial reference count
252 * Outs : If success return 0, otherwise return error code
253 ******************************************************************************/
254 int HLH_Ref::New (UINT32 unRef)
256 int nRetVal;
257 T * ptObj = NULL;
259 Destroy ();
261 ptObj = new T;
262 if (ptObj == NULL) {
263 HLH_DEBUG ( HLH_DEBUG_UTILS, ("create new T class failed") );
264 return HLH_REF_ERR_FAILED;
267 nRetVal = RefNew (ptObj, unRef);
269 return nRetVal;
272 /******************************************************************************
273 * Func : HLH_Ref::Ref
274 * Desc : Refer to HLH_Ref
275 * Args : zhrRef HLH_Ref instance to be refered
276 * unRef initial reference count of this HLH_Ref
277 * Outs : If success return 0, otherwise return error code
278 ******************************************************************************/
279 template <class T>
280 int HLH_Ref::Ref (const HLH_Ref &zhrRef, UINT32 unRef = 1)
282 // Destroy this reference first
283 Destroy ();
285 // Copy member
286 m_punRef = zhrRef.m_punRef;
287 m_ptObj = zhrRef.m_ptObj;
288 m_bDeconstruct = zhrRef.m_bDeconstruct;
289 m_zrtRefType = zhrRef.m_zrtRefType;
290 m_pvReleaseFunc = zhrRef.m_pvReleaseFunc;
291 m_pvReleaseOther = zhrRef.m_pvReleaseOther;
293 // Add reference only if not empty reference
294 m_unRef = unRef;
296 if (m_ptObj) {
297 ASSERT (zhrRef.m_unRef != 0);
298 ASSERT (zhrRef.m_punRef != NULL);
299 ASSERT (zhrRef.m_unRef <= *zhrRef.m_punRef);
301 *m_punRef += m_unRef;
304 return *this;
308 /******************************************************************************
309 * Func : HLH_Ref::RefNew
310 * Desc : Refer to a pointer created by new method
311 * Args : ptObj pointer of object to be refered
312 * unRef initial reference count of this pointer
313 * Outs :
314 ******************************************************************************/
315 template <class T>
316 int HLH_Ref::RefNew (T *ptObj = NULL, UINT32 unRef = 1)
318 UINT32 *punRef = NULL;
320 // Destroy this reference first
321 Destroy ();
323 // Check if input pointer empty
324 if (ptObj == NULL) {
325 HLH_DEBUG ( HLH_DEBUG_UTILS, ("refer NULL pointer") );
326 return HLH_REF_ERR_CANNT_REFER;
329 // Refer this pointer
330 punRef = (UINT32*) malloc ( sizeof(UINT32) );
331 if (punRef == NULL) {
332 HLH_DEBUG ( HLH_DEBUG_UTILS, ("memory allocate global reference count failed") );
333 goto failed;
336 m_ptObj = ptObj;
337 m_unRef = unRef;
338 *punRef = unRef;
339 m_punRef = punRef;
340 m_bDeconstruct = false;
341 m_zrtRefType = REF_TYPE_NEW;
342 m_pvReleaseFunc = NULL;
343 m_pvReleaseOther = NULL;
345 return 0;
347 failed:
348 if (punRef != NULL) {
349 free (punRef);
350 punRef = NULL;
353 return HLH_REF_ERR_CANNT_REFER;
356 /******************************************************************************
357 * Func : HLH_Ref::RefThis
358 * Desc : Refer to a pointer that takes only this pointer to release
359 * Args : ptObj pointer of object to be refered
360 * zrtRelease release function of \c ptObj
361 * bDeconstruct whether this T class should be deconstruct before
362 * release
363 * unRef initial reference count of this pointer
364 * Outs : If success return 0, otherwise return error code
365 ******************************************************************************/
366 template <class T>
367 int RefThis (T *ptObj = NULL, ReleaseThisFunc zrtRelease = free,
368 bool bDeconstruct = true, UINT32 unRef = 1)
370 UINT32 *punRef = NULL;
372 // Destroy this reference first
373 Destroy ();
375 // Check if input pointer empty
376 if (ptObj == NULL) {
377 HLH_DEBUG ( HLH_DEBUG_UTILS, ("refer NULL pointer") );
378 return HLH_REF_ERR_CANNT_REFER;
381 // Refer this pointer
382 punRef = (UINT32*) malloc ( sizeof(UINT32) );
383 if (punRef == NULL) {
384 HLH_DEBUG ( HLH_DEBUG_UTILS, ("memory allocate global reference count failed") );
385 goto failed;
388 m_ptObj = ptObj;
389 m_unRef = unRef;
390 *punRef = unRef;
391 m_punRef = punRef;
392 m_bDeconstruct = bDeconstruct;
393 m_zrtRefType = REF_TYPE_THIS;
394 m_pvReleaseFunc = zrtRelease;
395 m_pvReleaseOther = NULL;
397 return 0;
399 failed:
400 if (punRef != NULL) {
401 free (punRef);
402 punRef = NULL;
405 return HLH_REF_ERR_CANNT_REFER;
408 /******************************************************************************
409 * Func : HLH_Ref::RefOther
410 * Desc : Refer to a pointer that takes this point and other pointer to release it
411 * Args : ptObj pointer of object to be refered
412 * zroRelease release function of \c ptObj
413 * pvOther the other argument of zroRelease
414 * bDeconstruct whether this T class should be deconstruct before
415 * release
416 * unRef initial reference count of this pointer
417 * Outs : If success return 0, otherwise return error code
418 ******************************************************************************/
419 template <class T>
420 int HLH_Ref::RefOther (T *ptObj = NULL, ReleaseOtherFunc zroRelease = NULL,
421 void *pvOther = NULL, bool bDeconstruct = false, pvUINT32 unRef = 1)
423 UINT32 *punRef = NULL;
425 // Destroy this reference first
426 Destroy ();
428 // Check if input pointer empty
429 if (ptObj == NULL) {
430 HLH_DEBUG ( HLH_DEBUG_UTILS, ("refer NULL pointer") );
431 return HLH_REF_ERR_CANNT_REFER;
434 // Refer this pointer
435 punRef = (UINT32*) malloc ( sizeof(UINT32) );
436 if (punRef == NULL) {
437 HLH_DEBUG ( HLH_DEBUG_UTILS, ("memory allocate global reference count failed") );
438 goto failed;
441 m_ptObj = ptObj;
442 m_unRef = unRef;
443 *punRef = unRef;
444 m_punRef = punRef;
445 m_bDeconstruct = bDeconstruct;
446 m_zrtRefType = REF_TYPE_OTHER;
447 m_pvReleaseFunc = zroRelease;
448 m_pvReleaseOther = pvOther;
450 return 0;
452 failed:
453 if (punRef != NULL) {
454 free (punRef);
455 punRef = NULL;
458 return HLH_REF_ERR_CANNT_REFER;
461 /******************************************************************************
462 * Func : HLH_Ref::AddRef
463 * Desc : Add reference to this pointer (avoid to use this after all)
464 * Args : unRef reference count to add
465 * Outs : If success return 0, otherwise return error code
466 ******************************************************************************/
467 template <class T>
468 int HLH_Ref::AddRef (UINT32 unRef)
470 if (m_ptObj == NULL) {
471 HLH_DEBUG ( HLH_DEBUG_UTILS, ("add reference to empty reference") );
472 return HLH_REF_ERR_NOT_REFERED;
475 ASSERT (m_unRef != 0);
476 ASSERT (m_punRef != NULL);
477 ASSERT (*m_punRef >= m_unRef);
479 // Add reference to this pointer
480 m_unRef += unRef;
481 *m_punRef += unRef;
483 return 0;
486 /******************************************************************************
487 * Func : HLH_Ref::Release
488 * Desc : Release reference to this pointer (avoid to use this after all)
489 * Args : unRef reference count to release
490 * Outs : If success return the number of reference count released,
491 * otherwise return error code
492 ******************************************************************************/
493 template <class T>
494 int HLH_Ref::Release (UINT32 unRef)
496 if (m_ptObj == NULL) {
497 HLH_DEBUG ( HLH_DEBUG_UTILS, ("release empty reference") );
498 return HLH_REF_ERR_NOT_REFERED;
501 ASSERT (m_unRef != 0);
502 ASSERT (m_punRef != NULL);
503 ASSERT (*m_punRef >= m_unRef);
505 // release reference to this pointer
506 if (unRef > m_unRef) {
507 unRef = m_unRef;
508 HLH_DEBUG ( HLH_DEBUG_UTILS,
509 ("reference count released larger than this reference count") );
511 m_unRef -= unRef;
512 *m_punRef -= unRef;
514 // Release this pointer if this reference count run out
515 if (m_unRef == 0) {
516 Destroy ();
519 return unRef;
522 /******************************************************************************
523 * Func : HLH_Ref::Destroy
524 * Desc : Destroy the object refered,
525 * if release function is free(), deconstructor will be called
526 * Args : NONE
527 * Outs : NONE
528 ******************************************************************************/
529 template <class T>
530 void HLH_Ref::Destroy ()
532 if (m_ptObj == NULL) {
533 return;
536 ASSERT (m_unRef != 0);
537 ASSERT (m_punRef != NULL);
538 ASSERT (*m_punRef >= m_unRef);
540 *m_punRef -= m_unRef;
541 m_unRef = 0;
543 // Release this object if global reference run out
544 if (*m_punRef == 0) {
546 // Deconstruct this T class if requested
547 if ( m_bDeconstruct ) {
548 m_ptObj->T::~T ();
551 switch (m_zrtRefType) {
552 case REF_TYPE_NEW:
553 delete m_ptObj;
554 break;
555 case REF_TYPE_THIS:
556 ((ReleaseThisFunc)m_pvReleaseFunc) (m_ptObj);
557 break;
558 case REF_TYPE_OTHER:
559 ((ReleaseOtherFunc)m_pvReleaseFunc) (m_ptObj);
560 break;
561 default:
562 HLH_DEBUG ( HLH_DEBUG_UTILS,
563 ("unknown reference type %u", (UINT32)m_zrtRefType) );
564 break;
567 // Free global reference count space
568 free (m_punRef);
572 m_ptObj = NULL;
573 m_punRef = NULL;
579 #endif /* __HLH_REF_INC_20091118_155955_HENRY__ */