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