initial load of upstream version 1.06.32
[xmlrpc-c] / src / cpp / girmem.cpp
1 #include "pthreadx.h"
2 #include "xmlrpc-c/girerr.hpp"
3 using girerr::error;
4 #include "xmlrpc-c/girmem.hpp"
5
6 using namespace std;
7 using namespace girmem;
8
9
10 namespace girmem {
11
12
13 void
14 autoObject::incref() {
15     pthread_mutex_lock(&this->refcountLock);
16     ++this->refcount;
17     pthread_mutex_unlock(&this->refcountLock);
18 }
19
20
21
22 void
23 autoObject::decref(bool * const unreferencedP) {
24
25     if (this->refcount == 0)
26         throw(error("Decrementing ref count of unreferenced object"));
27     pthread_mutex_lock(&this->refcountLock);
28     --this->refcount;
29     *unreferencedP = (this->refcount == 0);
30     pthread_mutex_unlock(&this->refcountLock);
31 }
32  
33
34
35 autoObject::autoObject() {
36     int rc;
37
38     rc = pthread_mutex_init(&this->refcountLock, NULL);
39
40     if (rc != 0)
41         throw(error("Unable to initialize pthread mutex"));
42
43     this->refcount   = 0;
44 }
45
46
47
48 autoObject::~autoObject() {
49     if (this->refcount > 0)
50         throw(error("Destroying referenced object"));
51
52     int rc;
53
54     rc = pthread_mutex_destroy(&this->refcountLock);
55
56     if (rc != 0)
57         throw(error("Unable to destroy pthread mutex"));
58 }
59
60
61
62 autoObjectPtr::autoObjectPtr() : objectP(NULL) {}
63
64
65
66 autoObjectPtr::autoObjectPtr(autoObject * const objectP) {
67
68     // Note: When someone attempts to use this constructor with a null
69     // argument, it's normally because a 'new' of the autoObject
70     // failed, before calling the autoObject's constructor, thus
71     // generating a null pointer.
72
73     // E.g. the following code, where the system is out of memory:
74     //
75     //    class client    : public autoObject    { ... }
76     //    class clientPtr : public autoObjectPtr { ... }
77     //    clientPtr clientP(new client);
78
79     if (objectP == NULL)
80         throw(error("Object creation failed; trying to create autoObjectPtr "
81                     "ith a null autoObject pointer"));
82         
83     this->objectP = objectP;
84     objectP->incref();
85 }
86
87
88
89 autoObjectPtr::autoObjectPtr(autoObjectPtr const& autoObjectPtr) {
90     // copy constructor
91
92     this->objectP = autoObjectPtr.objectP;
93     if (this->objectP)
94         this->objectP->incref();
95 }
96     
97  
98
99 autoObjectPtr::~autoObjectPtr() {
100
101     this->unpoint();
102 }
103
104
105  
106 void
107 autoObjectPtr::point(autoObject * const objectP) {
108
109     if (this->objectP != NULL)
110         throw(error("Already pointing"));
111     this->objectP = objectP;
112     objectP->incref();
113 }
114
115
116
117 void
118 autoObjectPtr::unpoint() {
119
120     if (this->objectP) {
121         bool dead;
122         this->objectP->decref(&dead);
123         if (dead)
124             delete(this->objectP);
125     }
126 }
127
128
129
130 autoObjectPtr
131 autoObjectPtr::operator=(autoObjectPtr const& autoObjectPtr) {
132
133     if (this->objectP != NULL)
134         throw(error("Already pointing"));
135     this->objectP = autoObjectPtr.objectP;
136     this->objectP->incref();
137
138     return *this;
139 }
140
141    
142
143 autoObject *
144 autoObjectPtr::operator->() const {
145     return this->objectP;
146 }
147
148
149
150 autoObject *
151 autoObjectPtr::get() const {
152
153     return this->objectP;
154 }
155
156 } // namespace