BWAPI
|
00001 // Protocol Buffers - Google's data interchange format 00002 // Copyright 2008 Google Inc. All rights reserved. 00003 // http://code.google.com/p/protobuf/ 00004 // 00005 // Redistribution and use in source and binary forms, with or without 00006 // modification, are permitted provided that the following conditions are 00007 // met: 00008 // 00009 // * Redistributions of source code must retain the above copyright 00010 // notice, this list of conditions and the following disclaimer. 00011 // * Redistributions in binary form must reproduce the above 00012 // copyright notice, this list of conditions and the following disclaimer 00013 // in the documentation and/or other materials provided with the 00014 // distribution. 00015 // * Neither the name of Google Inc. nor the names of its 00016 // contributors may be used to endorse or promote products derived from 00017 // this software without specific prior written permission. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 00031 // Author: kenton@google.com (Kenton Varda) 00032 // 00033 // emulates google3/base/once.h 00034 // 00035 // This header is intended to be included only by internal .cc files and 00036 // generated .pb.cc files. Users should not use this directly. 00037 // 00038 // This is basically a portable version of pthread_once(). 00039 // 00040 // This header declares three things: 00041 // * A type called ProtobufOnceType. 00042 // * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type 00043 // ProtobufOnceType. This is the only legal way to declare such a variable. 00044 // The macro may only be used at the global scope (you cannot create local 00045 // or class member variables of this type). 00046 // * A function GogoleOnceInit(ProtobufOnceType* once, void (*init_func)()). 00047 // This function, when invoked multiple times given the same ProtobufOnceType 00048 // object, will invoke init_func on the first call only, and will make sure 00049 // none of the calls return before that first call to init_func has finished. 00050 // 00051 // This implements a way to perform lazy initialization. It's more efficient 00052 // than using mutexes as no lock is needed if initialization has already 00053 // happened. 00054 // 00055 // Example usage: 00056 // void Init(); 00057 // GOOGLE_PROTOBUF_DECLARE_ONCE(once_init); 00058 // 00059 // // Calls Init() exactly once. 00060 // void InitOnce() { 00061 // GoogleOnceInit(&once_init, &Init); 00062 // } 00063 // 00064 // Note that if GoogleOnceInit() is called before main() has begun, it must 00065 // only be called by the thread that will eventually call main() -- that is, 00066 // the thread that performs dynamic initialization. In general this is a safe 00067 // assumption since people don't usually construct threads before main() starts, 00068 // but it is technically not guaranteed. Unfortunately, Win32 provides no way 00069 // whatsoever to statically-initialize its synchronization primitives, so our 00070 // only choice is to assume that dynamic initialization is single-threaded. 00071 00072 #ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__ 00073 #define GOOGLE_PROTOBUF_STUBS_ONCE_H__ 00074 00075 #include <google/protobuf/stubs/common.h> 00076 00077 #ifndef _WIN32 00078 #include <pthread.h> 00079 #endif 00080 00081 namespace google { 00082 namespace protobuf { 00083 00084 #ifdef _WIN32 00085 00086 struct ProtobufOnceInternal; 00087 00088 struct LIBPROTOBUF_EXPORT ProtobufOnceType { 00089 ProtobufOnceType(); 00090 ~ProtobufOnceType(); 00091 void Init(void (*init_func)()); 00092 00093 volatile bool initialized_; 00094 ProtobufOnceInternal* internal_; 00095 }; 00096 00097 #define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ 00098 ::google::protobuf::ProtobufOnceType NAME 00099 00100 inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { 00101 // Note: Double-checked locking is safe on x86. 00102 if (!once->initialized_) { 00103 once->Init(init_func); 00104 } 00105 } 00106 00107 #else 00108 00109 typedef pthread_once_t ProtobufOnceType; 00110 00111 #define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ 00112 pthread_once_t NAME = PTHREAD_ONCE_INIT 00113 00114 inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { 00115 pthread_once(once, init_func); 00116 } 00117 00118 #endif 00119 00120 } // namespace protobuf 00121 } // namespace google 00122 00123 #endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__