xref: /titanic_41/usr/src/cmd/lms/SyncLib/Include/SPtr.h (revision 617e2443dfc17fe44fd44c0675d6aad2ffc9df42)
1*617e2443SMark Logan /*******************************************************************************
2*617e2443SMark Logan  * Copyright (C) 2004-2008 Intel Corp. All rights reserved.
3*617e2443SMark Logan  *
4*617e2443SMark Logan  * Redistribution and use in source and binary forms, with or without
5*617e2443SMark Logan  * modification, are permitted provided that the following conditions are met:
6*617e2443SMark Logan  *
7*617e2443SMark Logan  *  - Redistributions of source code must retain the above copyright notice,
8*617e2443SMark Logan  *    this list of conditions and the following disclaimer.
9*617e2443SMark Logan  *
10*617e2443SMark Logan  *  - Redistributions in binary form must reproduce the above copyright notice,
11*617e2443SMark Logan  *    this list of conditions and the following disclaimer in the documentation
12*617e2443SMark Logan  *    and/or other materials provided with the distribution.
13*617e2443SMark Logan  *
14*617e2443SMark Logan  *  - Neither the name of Intel Corp. nor the names of its
15*617e2443SMark Logan  *    contributors may be used to endorse or promote products derived from this
16*617e2443SMark Logan  *    software without specific prior written permission.
17*617e2443SMark Logan  *
18*617e2443SMark Logan  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19*617e2443SMark Logan  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*617e2443SMark Logan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*617e2443SMark Logan  * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
22*617e2443SMark Logan  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*617e2443SMark Logan  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*617e2443SMark Logan  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*617e2443SMark Logan  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*617e2443SMark Logan  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*617e2443SMark Logan  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*617e2443SMark Logan  * POSSIBILITY OF SUCH DAMAGE.
29*617e2443SMark Logan  *******************************************************************************/
30*617e2443SMark Logan 
31*617e2443SMark Logan //////////////////////////////////////////////////////////////////////////
32*617e2443SMark Logan //  SPtr.h
33*617e2443SMark Logan //
34*617e2443SMark Logan //  This is a smart pointer class. It receives an initialized object in
35*617e2443SMark Logan //  the constructor, and maintains a reference count to this object. It
36*617e2443SMark Logan //  deletes the object only when the reference count reaches 0.
37*617e2443SMark Logan //
38*617e2443SMark Logan //////////////////////////////////////////////////////////////////////////
39*617e2443SMark Logan 
40*617e2443SMark Logan #ifndef _SPTR_H_
41*617e2443SMark Logan #define _SPTR_H_
42*617e2443SMark Logan 
43*617e2443SMark Logan #include <memory>
44*617e2443SMark Logan #include "Semaphore.h"
45*617e2443SMark Logan 
46*617e2443SMark Logan template
47*617e2443SMark Logan <class T>
48*617e2443SMark Logan class SPtr
49*617e2443SMark Logan {
50*617e2443SMark Logan public:
51*617e2443SMark Logan 	// constructor
52*617e2443SMark Logan 	explicit SPtr(T *ptr_p = 0) :
_ptr(ptr_p)53*617e2443SMark Logan 		_ptr(ptr_p),
54*617e2443SMark Logan 		_pref_count(new int(1)),
55*617e2443SMark Logan 		_psem(new Semaphore(1)) {}
56*617e2443SMark Logan 
57*617e2443SMark Logan 	// copy constructor
58*617e2443SMark Logan 	template<class X>
SPtr(const SPtr<X> & other_sptr_p)59*617e2443SMark Logan 	SPtr(const SPtr<X> &other_sptr_p)
60*617e2443SMark Logan 	{
61*617e2443SMark Logan 		other_sptr_p.getSem()->acquire();
62*617e2443SMark Logan 		_ptr = other_sptr_p.get();
63*617e2443SMark Logan 		_pref_count = other_sptr_p.getRefcnt();
64*617e2443SMark Logan 		_psem = other_sptr_p.getSem();
65*617e2443SMark Logan 		++(*_pref_count);
66*617e2443SMark Logan 		_psem->release();
67*617e2443SMark Logan 	}
68*617e2443SMark Logan 
SPtr(const SPtr & other_sptr_p)69*617e2443SMark Logan 	SPtr(const SPtr &other_sptr_p)
70*617e2443SMark Logan 	{
71*617e2443SMark Logan 		other_sptr_p.getSem()->acquire();
72*617e2443SMark Logan 		_ptr = other_sptr_p.get();
73*617e2443SMark Logan 		_pref_count = other_sptr_p.getRefcnt();
74*617e2443SMark Logan 		_psem = other_sptr_p.getSem();
75*617e2443SMark Logan 		++(*_pref_count);
76*617e2443SMark Logan 		_psem->release();
77*617e2443SMark Logan 	}
78*617e2443SMark Logan 
79*617e2443SMark Logan 	// destructor
~SPtr()80*617e2443SMark Logan 	~SPtr()
81*617e2443SMark Logan 	{
82*617e2443SMark Logan 		_psem->acquire();
83*617e2443SMark Logan 		if (--(*_pref_count) == 0) {
84*617e2443SMark Logan 			// delete pointer only on last destruction
85*617e2443SMark Logan 			delete _pref_count;
86*617e2443SMark Logan 			delete _psem;
87*617e2443SMark Logan 			if (_ptr) {
88*617e2443SMark Logan 				delete _ptr;
89*617e2443SMark Logan 			}
90*617e2443SMark Logan 			_ptr = 0;
91*617e2443SMark Logan 		} else {
92*617e2443SMark Logan 			_psem->release();
93*617e2443SMark Logan 		}
94*617e2443SMark Logan 	}
95*617e2443SMark Logan 
96*617e2443SMark Logan 	// operator=
97*617e2443SMark Logan 	// if 'this' already points to an object, unreference it
98*617e2443SMark Logan 	template<class X>
99*617e2443SMark Logan 	SPtr &operator= (const SPtr<X> &other_sptr_p)
100*617e2443SMark Logan 	{
101*617e2443SMark Logan 		if ((void *)&other_sptr_p == this) {
102*617e2443SMark Logan 			return *this;
103*617e2443SMark Logan 		}
104*617e2443SMark Logan 		_psem->acquire();
105*617e2443SMark Logan 		if (--(*_pref_count) == 0) {
106*617e2443SMark Logan 			delete _pref_count;
107*617e2443SMark Logan 			delete _psem;
108*617e2443SMark Logan 			if (_ptr) {
109*617e2443SMark Logan 				delete _ptr;
110*617e2443SMark Logan 			}
111*617e2443SMark Logan 		} else {
112*617e2443SMark Logan 			_psem->release();
113*617e2443SMark Logan 		}
114*617e2443SMark Logan 		other_sptr_p.getSem()->acquire();
115*617e2443SMark Logan 		_ptr = (T *)other_sptr_p.get();
116*617e2443SMark Logan 		_pref_count = other_sptr_p.getRefcnt();
117*617e2443SMark Logan 		_psem = other_sptr_p.getSem();
118*617e2443SMark Logan 		++(*_pref_count);
119*617e2443SMark Logan 		_psem->release();
120*617e2443SMark Logan 		return *this;
121*617e2443SMark Logan 	}
122*617e2443SMark Logan 
123*617e2443SMark Logan 	SPtr &operator=(const SPtr &other_sptr_p)
124*617e2443SMark Logan 	{
125*617e2443SMark Logan 		if (&other_sptr_p == this) {
126*617e2443SMark Logan 			return *this;
127*617e2443SMark Logan 		}
128*617e2443SMark Logan 		_psem->acquire();
129*617e2443SMark Logan 		if (--(*_pref_count) == 0) {
130*617e2443SMark Logan 			delete _pref_count;
131*617e2443SMark Logan 			delete _psem;
132*617e2443SMark Logan 			if (_ptr) {
133*617e2443SMark Logan 				delete _ptr;
134*617e2443SMark Logan 			}
135*617e2443SMark Logan 		} else {
136*617e2443SMark Logan 			_psem->release();
137*617e2443SMark Logan 		}
138*617e2443SMark Logan 		other_sptr_p.getSem()->acquire();
139*617e2443SMark Logan 		_ptr = other_sptr_p.get();
140*617e2443SMark Logan 		_pref_count = other_sptr_p.getRefcnt();
141*617e2443SMark Logan 		_psem = other_sptr_p.getSem();
142*617e2443SMark Logan 		++(*_pref_count);
143*617e2443SMark Logan 		_psem->release();
144*617e2443SMark Logan 		return *this;
145*617e2443SMark Logan 	}
146*617e2443SMark Logan 
147*617e2443SMark Logan 	// operator*
148*617e2443SMark Logan 	T &operator*() const
149*617e2443SMark Logan 	{
150*617e2443SMark Logan 		return *_ptr;
151*617e2443SMark Logan 	}
152*617e2443SMark Logan 
153*617e2443SMark Logan 	// operator->
154*617e2443SMark Logan 	T *operator->() const
155*617e2443SMark Logan 	{
156*617e2443SMark Logan 		return _ptr;
157*617e2443SMark Logan 	}
158*617e2443SMark Logan 
159*617e2443SMark Logan 	// get - return inner pointer
get()160*617e2443SMark Logan 	T *get() const
161*617e2443SMark Logan 	{
162*617e2443SMark Logan 		return _ptr;
163*617e2443SMark Logan 	}
164*617e2443SMark Logan 
getRefcnt()165*617e2443SMark Logan 	int *getRefcnt() const
166*617e2443SMark Logan 	{
167*617e2443SMark Logan 		return _pref_count;
168*617e2443SMark Logan 	}
169*617e2443SMark Logan 
getSem()170*617e2443SMark Logan 	Semaphore *getSem() const
171*617e2443SMark Logan 	{
172*617e2443SMark Logan 		return _psem;
173*617e2443SMark Logan 	}
174*617e2443SMark Logan 
175*617e2443SMark Logan private:
176*617e2443SMark Logan 	// the pointer itself
177*617e2443SMark Logan 	T *_ptr;
178*617e2443SMark Logan 	// a pointer to the reference count
179*617e2443SMark Logan 	int *_pref_count;
180*617e2443SMark Logan 	Semaphore *_psem;
181*617e2443SMark Logan } ;
182*617e2443SMark Logan 
183*617e2443SMark Logan template
184*617e2443SMark Logan <class T>
185*617e2443SMark Logan inline bool operator==(const SPtr<T> &x, const SPtr<T> &y) {
186*617e2443SMark Logan 	return(x.get() == y.get());
187*617e2443SMark Logan }
188*617e2443SMark Logan 
189*617e2443SMark Logan template
190*617e2443SMark Logan <class T>
191*617e2443SMark Logan inline bool operator!=(const SPtr<T> &x, const SPtr<T> &y) {
192*617e2443SMark Logan 	return(x.get() != y.get());
193*617e2443SMark Logan }
194*617e2443SMark Logan 
195*617e2443SMark Logan #endif // _SPTR_H_
196*617e2443SMark Logan 
197