File: referenced.h

package info (click to toggle)
openalpp-cvs 20041206-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,796 kB
  • ctags: 549
  • sloc: cpp: 3,891; makefile: 154; ansic: 56; sh: 5
file content (143 lines) | stat: -rwxr-xr-x 4,750 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/

#ifndef OPENALPP_REFERENCED
#define OPENALPP_REFERENCED 1


#include <openalpp/export.h>

// #define THREAD_SAFE_REF_UNREF 1

#ifdef THREAD_SAFE_REF_UNREF
    #include <OpenThreads/ScopedLock>
    #include <OpenThreads/Mutex>
#endif

namespace openalpp {


// forward declar, declared after Refenced below.
class DeleteHandler;


/** Base class from providing referencing counted objects.*/
class OPENALPP_API Referenced
{

    public:
        Referenced() 
        {
           
           _refCount=0;
        }
        Referenced(const Referenced&) {
            _refCount=0;
        }

        inline Referenced& operator = (const Referenced&) { return *this; }

        friend class DeleteHandler;

        /** Set a DeleteHandler to which deletion of all referenced counted objects
          * will be delegated to.*/
        static void setDeleteHandler(DeleteHandler* handler);

        /** Get a DeleteHandler.*/
        static DeleteHandler* getDeleteHandler();


        /** increment the reference count by one, indicating that 
            this object has another pointer which is referencing it.*/
        inline void ref() const
        { 
#ifdef THREAD_SAFE_REF_UNREF
            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex); 
#endif
            ++_refCount;
        }
        
        /** decrement the reference count by one, indicating that 
            a pointer to this object is referencing it.  If the
            reference count goes to zero, it is assumed that this object
            is no longer referenced and is automatically deleted.*/
        inline void unref() const;
        
        /** decrement the reference count by one, indicating that 
            a pointer to this object is referencing it.  However, do
            not delete it, even if ref count goes to 0.  Warning, unref_nodelete() 
            should only be called if the user knows exactly who will
            be resonsible for, one should prefer unref() over unref_nodelete() 
            as the later can lead to memory leaks.*/
        inline void unref_nodelete() const { --_refCount; }
        
        /** return the number pointers currently referencing this object. */
        inline int referenceCount() const { return _refCount; }

       
    protected:
        virtual ~Referenced();
        
#ifdef THREAD_SAFE_REF_UNREF
        mutable OpenThreads::Mutex  _refMutex;
#endif
        mutable int                 _refCount;
        
};


/** Class for override the default delete behavior so that users can implment their own object
  * deletion schemes.  This might be done to help implement protection of multiple threads from deleting
  * objects unintentionally.
  * Note, the DeleteHandler cannot itself be reference counted, otherwise it
  * would be responsible for deleting itself!
  * An static auto_ptr<> is used internally in Referenced.cpp to manage the 
  * DeleteHandler's memory.*/
class DeleteHandler
{
    public:

        virtual ~DeleteHandler() {}

        /** flush any cache of objects that need to be deleted by doing an actual delete.*/
        virtual void flush() {}
        
        inline void doDelete(const Referenced* object) { delete object; }
         
        /** Request the deletion of an object. 
          * Depending on users implementation of DeleteHandler, the delete of the object may occur 
          * straight away or be delayed until doDelete is called.
          * The default implementation does a delete straight away.*/
        virtual void requestDelete(const Referenced* object) { doDelete(object); }
};

inline void Referenced::unref() const
{
    bool needDelete = false;
    {
#ifdef THREAD_SAFE_REF_UNREF
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex); 
#endif
        --_refCount;
        needDelete = _refCount<=0;
    }
    if (needDelete)
    {
        if (getDeleteHandler()) getDeleteHandler()->requestDelete(this);
        else delete this;
    }
}

}

#endif