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 #include <salhelper/salhelperdllapi.h> 40 41 namespace salhelper { 42 43 /** A simple base implementation for reference-counted objects. 44 45 Classes that want to implement a reference-counting mechanism based on the 46 acquire()/release() interface should derive from this class. 47 48 The reason to have class local operators new and delete here is technical. 49 Imagine a class D derived from SimpleReferenceObject, but implemented in 50 another shared library that happens to use different global operators new 51 and delete from those used in this shared library (which, sadly, seems to 52 be possible with shared libraries). Now, without the class local 53 operators new and delete here, a code sequence like "new D" would use the 54 global operator new as found in the other shared library, while the code 55 sequence "delete this" in release() would use the global operator delete 56 as found in this shared library---and these two operators would not be 57 guaranteed to match. 58 59 There are no overloaded operators new and delete for placement new here, 60 because it is felt that the concept of placement new does not work well 61 with the concept of reference-counted objects; so it seems best to simply 62 leave those operators out. 63 64 The same problem as with operators new and delete would also be there with 65 operators new[] and delete[]. But since arrays of reference-counted 66 objects are of no use, anyway, it seems best to simply declare and not 67 define (private) operators new[] and delete[]. 68 69 Note how during the move to gbuild, the delete[] had to be implemented, 70 as missing vector delete errors stopped linking. The small consolation is 71 that is a private method, so it may as well not exist. Right? 72 */ 73 #if defined _MSC_VER 74 class SimpleReferenceObject 75 #else 76 class SALHELPER_DLLPUBLIC SimpleReferenceObject 77 #endif 78 { 79 public: 80 inline SimpleReferenceObject() SAL_THROW(()): m_nCount(0) {} 81 82 /** @ATTENTION 83 The results are undefined if, for any individual instance of 84 SimpleReferenceObject, the total number of calls to acquire() exceeds 85 the total number of calls to release() by a platform dependent amount 86 (which, hopefully, is quite large). 87 */ acquire()88 inline void acquire() SAL_THROW(()) 89 { osl_incrementInterlockedCount(&m_nCount); } 90 release()91 inline void release() SAL_THROW(()) 92 { if (osl_decrementInterlockedCount(&m_nCount) == 0) delete this; } 93 94 /** see general class documentation 95 */ 96 SALHELPER_DLLPUBLIC static void * operator new(std::size_t nSize) SAL_THROW((std::bad_alloc)); 97 98 /** see general class documentation 99 */ 100 SALHELPER_DLLPUBLIC static void * operator new(std::size_t nSize, 101 std::nothrow_t const & rNothrow) 102 SAL_THROW(()); 103 104 /** see general class documentation 105 */ 106 SALHELPER_DLLPUBLIC static void operator delete(void * pPtr) SAL_THROW(()); 107 108 /** see general class documentation 109 */ 110 SALHELPER_DLLPUBLIC static void operator delete(void * pPtr, std::nothrow_t const & rNothrow) 111 SAL_THROW(()); 112 113 protected: 114 SALHELPER_DLLPUBLIC virtual ~SimpleReferenceObject() SAL_THROW(()); 115 116 private: 117 oslInterlockedCount m_nCount; 118 119 /** not implemented 120 @internal 121 */ 122 SimpleReferenceObject(SimpleReferenceObject &); 123 124 /** not implemented 125 @internal 126 */ 127 void operator =(SimpleReferenceObject); 128 129 /** not implemented (see general class documentation) 130 @internal 131 */ 132 static void * operator new[](std::size_t); 133 134 /** not implemented (see general class documentation) 135 @internal 136 */ 137 SALHELPER_DLLPUBLIC static void operator delete[](void * pPtr); 138 }; 139 140 } 141 142 #endif // _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ 143