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