1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ 25 #define _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ 26 27 #include "osl/interlck.h" 28 #include "sal/types.h" 29 30 #ifndef INCLUDED_CSTDDEF 31 #include <cstddef> 32 #define INCLUDED_CSTDDEF 33 #endif 34 #ifndef INCLUDED_NEW 35 #include <new> 36 #define INCLUDED_NEW 37 #endif 38 39 namespace salhelper { 40 41 /** A simple base implementation for reference-counted objects. 42 43 Classes that want to implement a reference-counting mechanism based on the 44 acquire()/release() interface should derive from this class. 45 46 The reason to have class local operators new and delete here is technical. 47 Imagine a class D derived from SimpleReferenceObject, but implemented in 48 another shared library that happens to use different global operators new 49 and delete from those used in this shared library (which, sadly, seems to 50 be possible with shared libraries). Now, without the class local 51 operators new and delete here, a code sequence like "new D" would use the 52 global operator new as found in the other shared library, while the code 53 sequence "delete this" in release() would use the global operator delete 54 as found in this shared library---and these two operators would not be 55 guaranteed to match. 56 57 There are no overloaded operators new and delete for placement new here, 58 because it is felt that the concept of placement new does not work well 59 with the concept of reference-counted objects; so it seems best to simply 60 leave those operators out. 61 62 The same problem as with operators new and delete would also be there with 63 operators new[] and delete[]. But since arrays of reference-counted 64 objects are of no use, anyway, it seems best to simply declare and not 65 define (private) operators new[] and delete[]. 66 */ 67 class SimpleReferenceObject 68 { 69 public: 70 inline SimpleReferenceObject() SAL_THROW(()): m_nCount(0) {} 71 72 /** @ATTENTION 73 The results are undefined if, for any individual instance of 74 SimpleReferenceObject, the total number of calls to acquire() exceeds 75 the total number of calls to release() by a plattform dependent amount 76 (which, hopefully, is quite large). 77 */ acquire()78 inline void acquire() SAL_THROW(()) 79 { osl_incrementInterlockedCount(&m_nCount); } 80 release()81 inline void release() SAL_THROW(()) 82 { if (osl_decrementInterlockedCount(&m_nCount) == 0) delete this; } 83 84 /** see general class documentation 85 */ 86 static void * operator new(std::size_t nSize) SAL_THROW((std::bad_alloc)); 87 88 /** see general class documentation 89 */ 90 static void * operator new(std::size_t nSize, 91 std::nothrow_t const & rNothrow) 92 SAL_THROW(()); 93 94 /** see general class documentation 95 */ 96 static void operator delete(void * pPtr) SAL_THROW(()); 97 98 /** see general class documentation 99 */ 100 static void operator delete(void * pPtr, std::nothrow_t const & rNothrow) 101 SAL_THROW(()); 102 103 protected: 104 virtual ~SimpleReferenceObject() SAL_THROW(()); 105 106 private: 107 oslInterlockedCount m_nCount; 108 109 /** not implemented 110 @internal 111 */ 112 SimpleReferenceObject(SimpleReferenceObject &); 113 114 /** not implemented 115 @internal 116 */ 117 void operator =(SimpleReferenceObject); 118 119 /** not implemented (see general class documentation) 120 @internal 121 */ 122 static void * operator new[](std::size_t); 123 124 /** not implemented (see general class documentation) 125 @internal 126 */ 127 static void operator delete[](void * pPtr); 128 }; 129 130 } 131 132 #endif // _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ 133