once.h (3697B) - Raw
1 /* 2 * Copyright (c) 2008-2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20 21 #ifndef __DISPATCH_ONCE__ 22 #define __DISPATCH_ONCE__ 23 24 #ifndef __DISPATCH_INDIRECT__ 25 #error "Please #include <dispatch/dispatch.h> instead of this file directly." 26 #include <dispatch/base.h> // for HeaderDoc 27 #endif 28 29 DISPATCH_ASSUME_NONNULL_BEGIN 30 DISPATCH_ASSUME_ABI_SINGLE_BEGIN 31 32 __BEGIN_DECLS 33 34 /*! 35 * @typedef dispatch_once_t 36 * 37 * @abstract 38 * A predicate for use with dispatch_once(). It must be initialized to zero. 39 * Note: static and global variables default to zero. 40 */ 41 DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead") 42 typedef intptr_t dispatch_once_t; 43 44 #if defined(__x86_64__) || defined(__i386__) || defined(__s390x__) 45 #define DISPATCH_ONCE_INLINE_FASTPATH 1 46 #elif defined(__APPLE__) 47 #define DISPATCH_ONCE_INLINE_FASTPATH 1 48 #else 49 #define DISPATCH_ONCE_INLINE_FASTPATH 0 50 #endif 51 52 /*! 53 * @function dispatch_once 54 * 55 * @abstract 56 * Execute a block once and only once. 57 * 58 * @param predicate 59 * A pointer to a dispatch_once_t that is used to test whether the block has 60 * completed or not. 61 * 62 * @param block 63 * The block to execute once. 64 * 65 * @discussion 66 * Always call dispatch_once() before using or testing any variables that are 67 * initialized by the block. 68 */ 69 #ifdef __BLOCKS__ 70 API_AVAILABLE(macos(10.6), ios(4.0)) 71 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 72 DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead") 73 void 74 dispatch_once(dispatch_once_t *predicate, 75 DISPATCH_NOESCAPE dispatch_block_t block); 76 77 #if DISPATCH_ONCE_INLINE_FASTPATH 78 DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 79 DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead") 80 void 81 _dispatch_once(dispatch_once_t *predicate, 82 DISPATCH_NOESCAPE dispatch_block_t block) 83 { 84 if (DISPATCH_EXPECT(*predicate, ~0l) != ~0l) { 85 dispatch_once(predicate, block); 86 } else { 87 dispatch_compiler_barrier(); 88 } 89 DISPATCH_COMPILER_CAN_ASSUME(*predicate == ~0l); 90 } 91 #undef dispatch_once 92 #define dispatch_once _dispatch_once 93 #endif 94 #endif // DISPATCH_ONCE_INLINE_FASTPATH 95 96 API_AVAILABLE(macos(10.6), ios(4.0)) 97 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 98 DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead") 99 void 100 dispatch_once_f(dispatch_once_t *predicate, void *_Nullable context, 101 dispatch_function_t function); 102 103 #if DISPATCH_ONCE_INLINE_FASTPATH 104 DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL1 DISPATCH_NONNULL3 105 DISPATCH_NOTHROW 106 DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead") 107 void 108 _dispatch_once_f(dispatch_once_t *predicate, void *_Nullable context, 109 dispatch_function_t function) 110 { 111 if (DISPATCH_EXPECT(*predicate, ~0l) != ~0l) { 112 dispatch_once_f(predicate, context, function); 113 } else { 114 dispatch_compiler_barrier(); 115 } 116 DISPATCH_COMPILER_CAN_ASSUME(*predicate == ~0l); 117 } 118 #undef dispatch_once_f 119 #define dispatch_once_f _dispatch_once_f 120 #endif // DISPATCH_ONCE_INLINE_FASTPATH 121 122 __END_DECLS 123 124 DISPATCH_ASSUME_ABI_SINGLE_END 125 DISPATCH_ASSUME_NONNULL_END 126 127 #endif