1 /*******************************************************************************
5 * Created : Wed 18 Nov 2009 03:59:55 PM CST
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 /*******************************************************************************
39 ******************************************************************************/
43 /******************************************************************************
46 ******************************************************************************/
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) {
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 (); }
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
);
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
137 // ==================== ACCESS =========================================
139 // Get internal pointer
142 // Reset the pointer to the initial pointer
149 // ==================== OPERATIONS =========================================
154 // ==================== MEMBER DATA =========================================
158 // Reference count of this reference
161 // Pointer to global reference count
166 // Pointer of this reference
169 // Whether deconstructor should be called
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 /******************************************************************************
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
)
204 /******************************************************************************
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
)
216 /******************************************************************************
218 * Desc : Reload of address resolve operator
220 * Outs : return reference of this pointer
221 ******************************************************************************/
222 T
& HLH_Ref::operator * () const
229 /******************************************************************************
231 * Desc : Reload of member access operator
233 * Outs : return this pointer
234 ******************************************************************************/
235 T
* HLH_Ref::operator -> () const
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
)
263 HLH_DEBUG ( HLH_DEBUG_UTILS
, ("create new T class failed") );
264 return HLH_REF_ERR_FAILED
;
267 nRetVal
= RefNew (ptObj
, unRef
);
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 ******************************************************************************/
280 int HLH_Ref::Ref (const HLH_Ref
&zhrRef
, UINT32 unRef
= 1)
282 // Destroy this reference first
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
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
;
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
314 ******************************************************************************/
316 int HLH_Ref::RefNew (T
*ptObj
= NULL
, UINT32 unRef
= 1)
318 UINT32
*punRef
= NULL
;
320 // Destroy this reference first
323 // Check if input pointer empty
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") );
340 m_bDeconstruct
= false;
341 m_zrtRefType
= REF_TYPE_NEW
;
342 m_pvReleaseFunc
= NULL
;
343 m_pvReleaseOther
= NULL
;
348 if (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
363 * unRef initial reference count of this pointer
364 * Outs : If success return 0, otherwise return error code
365 ******************************************************************************/
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
375 // Check if input pointer empty
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") );
392 m_bDeconstruct
= bDeconstruct
;
393 m_zrtRefType
= REF_TYPE_THIS
;
394 m_pvReleaseFunc
= zrtRelease
;
395 m_pvReleaseOther
= NULL
;
400 if (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
416 * unRef initial reference count of this pointer
417 * Outs : If success return 0, otherwise return error code
418 ******************************************************************************/
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
428 // Check if input pointer empty
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") );
445 m_bDeconstruct
= bDeconstruct
;
446 m_zrtRefType
= REF_TYPE_OTHER
;
447 m_pvReleaseFunc
= zroRelease
;
448 m_pvReleaseOther
= pvOther
;
453 if (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 ******************************************************************************/
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
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 ******************************************************************************/
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
) {
508 HLH_DEBUG ( HLH_DEBUG_UTILS
,
509 ("reference count released larger than this reference count") );
514 // Release this pointer if this reference count run out
522 /******************************************************************************
523 * Func : HLH_Ref::Destroy
524 * Desc : Destroy the object refered,
525 * if release function is free(), deconstructor will be called
528 ******************************************************************************/
530 void HLH_Ref::Destroy ()
532 if (m_ptObj
== NULL
) {
536 ASSERT (m_unRef
!= 0);
537 ASSERT (m_punRef
!= NULL
);
538 ASSERT (*m_punRef
>= m_unRef
);
540 *m_punRef
-= m_unRef
;
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
) {
551 switch (m_zrtRefType
) {
556 ((ReleaseThisFunc
)m_pvReleaseFunc
) (m_ptObj
);
559 ((ReleaseOtherFunc
)m_pvReleaseFunc
) (m_ptObj
);
562 HLH_DEBUG ( HLH_DEBUG_UTILS
,
563 ("unknown reference type %u", (UINT32
)m_zrtRefType
) );
567 // Free global reference count space
579 #endif /* __HLH_REF_INC_20091118_155955_HENRY__ */