X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fexternal%2Fandroid-emugl%2Fshared%2Femugl%2Fcommon%2Flazy_instance.h;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fexternal%2Fandroid-emugl%2Fshared%2Femugl%2Fcommon%2Flazy_instance.h;h=6641c93d3db992506658a932ecd7d2f2286d44fa;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/external/android-emugl/shared/emugl/common/lazy_instance.h b/src/type3_AndroidCloud/anbox-master/external/android-emugl/shared/emugl/common/lazy_instance.h new file mode 100644 index 0000000..6641c93 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/external/android-emugl/shared/emugl/common/lazy_instance.h @@ -0,0 +1,156 @@ +// Copyright (C) 2014 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef EMUGL_COMMON_LAZY_INSTANCE_H +#define EMUGL_COMMON_LAZY_INSTANCE_H + +#include + +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN 1 +# include +#endif + +namespace emugl { +namespace internal { + +// A LazyInstance is a helper template that can be used to perform +// thread-safe lazy initialization of static C++ objects without forcing +// the generation of C++ static constructors in the final executable. +// +// In a nutshell, you can replace a statement like: +// +// static Foo gFoo; +// +// With: +// +// static LazyInstance gFoo = LAZY_INSTANCE_INIT; +// +// In the first case, a hidden static C++ constructor is embedded in the +// final executable, and executed at *load* *time* to call the Foo::Foo +// constructor on the gFoo object. +// +// On the second case, gFoo will only be initialized lazily, i.e. the first +// time any code actually tries to access the variable. +// +// Note that access is slightly different, i.e.: +// +// gFoo.get() returns a reference to the lazy-initialized object. +// gFoo.ptr() returns a pointer to it. +// gFoo->Something() is equivalent to doing gFoo.ptr()->Something(). +// +// 'gFoo' is stored in the .bss section and this doesn't use heap allocation. +// This class can only be used to perform lazy initialization through the +// class' default constructor. For more specialized cases, you will have +// to create a derived class, e.g.: +// +// class FoorWithDefaultParams : public Foo { +// public: +// FooWithDefaultParams() : Foo() {} +// }; +// +// LazyInstance gFoo = LAZY_INSTANCE_INIT; +// +// The implementation of LazyInstance relies on atomic operations and +// POD-struct class definitions, i.e. one that doesn't have any constructor, +// destructor, virtual members, or private ones, and that can be +// zero-initialized at link time. +// +// You can also use LazyInstance<> instances as static local variables, +// e.g.: +// +// Foo* getFooSingleton() { +// static LazyInstance sFoo = LAZY_INSTANCE_INIT; +// return sFoo.ptr(); +// } +// +// This is useful on Windows which doesn't support thread-safe lazy +// initialization of static C++ local variables, or when the code is +// compiled with -fno-threadsafe-statics. +// +// This class is heavily inspired by Chromium's implementation of the +// same-named class (see $CHROMIUM/src/base/lazy_instance.h). + +// Atomic state variable type. Used to ensure to synchronize concurrent +// initialization and access without incurring the full cost of a mutex +// lock/unlock. +struct LazyInstanceState { + enum { + STATE_INIT = 0, + STATE_CONSTRUCTING = 1, + STATE_DONE = 2, + }; + + bool inInitState(); + bool needConstruction(); + void doneConstructing(); + +#ifdef _WIN32 + typedef LONG volatile AtomicType; +#else + typedef int volatile AtomicType; +#endif + + volatile AtomicType mState; +}; + +#define LAZY_INSTANCE_STATE_INIT \ + { ::emugl::internal::LazyInstanceState::STATE_INIT } + +} // namespace internal + +// LazyInstance template definition, see comment above for usage +// instructions. It is crucial to make this a POD-struct compatible +// type [1]. +// +// [1] http://en.wikipedia.org/wiki/Plain_Old_Data_Structures +// +template +struct LazyInstance { + bool hasInstance() const { return !mState.inInitState(); } + + T& get() const { return *ptr(); } + + T* ptr() const; + + const T* operator->() const { return ptr(); } + + T* operator->() { return ptr(); } + + T& operator*() { return get(); } + + // Really private, do not use. + union { + mutable internal::LazyInstanceState mState; + double mPadding; + }; + mutable char mStorage[sizeof(T)]; +}; + +// Initialization value, must resolve to all-0 to ensure the object +// instance is actually placed in the .bss +#define LAZY_INSTANCE_INIT { { LAZY_INSTANCE_STATE_INIT }, { 0 } } + +template +T* LazyInstance::ptr() const { + if (mState.needConstruction()) { + new (mStorage) T(); + mState.doneConstructing(); + } + return reinterpret_cast(mStorage); +} + +} // namespace emugl + +#endif // EMUGL_COMMON_LAZY_INSTANCE_H