1*9eab2a37SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9eab2a37SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9eab2a37SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9eab2a37SAndrew Rist * distributed with this work for additional information 6*9eab2a37SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9eab2a37SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9eab2a37SAndrew Rist * "License"); you may not use this file except in compliance 9*9eab2a37SAndrew Rist * with the License. You may obtain a copy of the License at 10*9eab2a37SAndrew Rist * 11*9eab2a37SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*9eab2a37SAndrew Rist * 13*9eab2a37SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9eab2a37SAndrew Rist * software distributed under the License is distributed on an 15*9eab2a37SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9eab2a37SAndrew Rist * KIND, either express or implied. See the License for the 17*9eab2a37SAndrew Rist * specific language governing permissions and limitations 18*9eab2a37SAndrew Rist * under the License. 19*9eab2a37SAndrew Rist * 20*9eab2a37SAndrew Rist *************************************************************/ 21*9eab2a37SAndrew Rist 22*9eab2a37SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #if !defined INCLUDED_OSL_DOUBLECHECKEDLOCKING_H 25cdf0e10cSrcweir #define INCLUDED_OSL_DOUBLECHECKEDLOCKING_H 26cdf0e10cSrcweir 27cdf0e10cSrcweir #if defined __cplusplus 28cdf0e10cSrcweir extern "C" { 29cdf0e10cSrcweir #endif /* __cplusplus */ 30cdf0e10cSrcweir 31cdf0e10cSrcweir /** A platform specific macro needed to make double-checked locking work. 32cdf0e10cSrcweir 33cdf0e10cSrcweir See 34cdf0e10cSrcweir <http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html> 35cdf0e10cSrcweir for a description of double-checked locking, why it is broken, and how it 36cdf0e10cSrcweir can be fixed. On platforms where it is necessary, this macro will expand 37cdf0e10cSrcweir to some memory barrier instruction. On many platforms, double-checked 38cdf0e10cSrcweir locking works as it is, though, so on those platforms this macro will be 39cdf0e10cSrcweir empty. This is a macro instead of a (C++ inline) function to allow for 40cdf0e10cSrcweir maximum performance in both C and C++. 41cdf0e10cSrcweir 42cdf0e10cSrcweir If possible, use the rtl_Instance template instead of explicitly spelling 43cdf0e10cSrcweir out the double-checked locking pattern. There are few cases where you 44cdf0e10cSrcweir will have to spell it out explicitly (e.g., the logic of a certain 45cdf0e10cSrcweir instance of the pattern is too complex to be mapped to the template, or 46cdf0e10cSrcweir some compiler refuses to compile a template instantiation due to internal 47cdf0e10cSrcweir compiler errors), though, and you should always call this macro at the 48cdf0e10cSrcweir right places then: 49cdf0e10cSrcweir 50cdf0e10cSrcweir static T * pInstance = 0; 51cdf0e10cSrcweir 52cdf0e10cSrcweir T * p = pInstance; 53cdf0e10cSrcweir if (!p) 54cdf0e10cSrcweir { 55cdf0e10cSrcweir Guard aGuard(aMutex); 56cdf0e10cSrcweir p = pInstance; 57cdf0e10cSrcweir if (!p) 58cdf0e10cSrcweir { 59cdf0e10cSrcweir p = ...; 60cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 61cdf0e10cSrcweir pInstance = p; 62cdf0e10cSrcweir } 63cdf0e10cSrcweir } 64cdf0e10cSrcweir else 65cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 66cdf0e10cSrcweir return p; 67cdf0e10cSrcweir 68cdf0e10cSrcweir One extra advantage of this macro is that it makes it easier to find all 69cdf0e10cSrcweir places where double-checked locking is used. 70cdf0e10cSrcweir */ 71cdf0e10cSrcweir #define OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER() /* empty */ 72cdf0e10cSrcweir 73cdf0e10cSrcweir #if defined __cplusplus 74cdf0e10cSrcweir } 75cdf0e10cSrcweir #endif /* __cplusplus */ 76cdf0e10cSrcweir 77cdf0e10cSrcweir #endif /* INCLUDED_OSL_DOUBLECHECKEDLOCKING_H */ 78