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