Introduce static init PiperOrigin-RevId: 791228365
diff --git a/c/enc/static_init.c b/c/enc/static_init.c new file mode 100644 index 0000000..4716fa1 --- /dev/null +++ b/c/enc/static_init.c
@@ -0,0 +1,47 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Central point for static initialization. */ + +#include "static_init.h" + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +static BROTLI_BOOL DoBrotliEncoderStaticInit(void) { + return BROTLI_TRUE; +} +#endif + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) +static BROTLI_BOOL kEarlyInitOk; +static __attribute__((constructor)) void BrotliEncoderStaticInitEarly(void) { + kEarlyInitOk = DoBrotliEncoderStaticInit(); +} +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +static BROTLI_BOOL kLazyInitOk; +void BrotliEncoderLazyStaticInitInner(void) { + kLazyInitOk = DoBrotliEncoderStaticInit(); +} +#endif + +BROTLI_BOOL BrotliEncoderEnsureStaticInit(void) { +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) + return BROTLI_TRUE; +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) + return kEarlyInitOk; +#else + return kLazyInitOk; +#endif +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif
diff --git a/c/enc/static_init.h b/c/enc/static_init.h new file mode 100644 index 0000000..bbe4f1d --- /dev/null +++ b/c/enc/static_init.h
@@ -0,0 +1,66 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Central point for static initialization. */ + +#ifndef THIRD_PARTY_BROTLI_ENC_STATIC_INIT_H_ +#define THIRD_PARTY_BROTLI_ENC_STATIC_INIT_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Static data is "initialized" in compile time. */ +#define BROTLI_STATIC_INIT_NONE 0 +/* Static data is initialized before "main". */ +#define BROTLI_STATIC_INIT_EARLY 1 +/* Static data is initialized when first encoder is created. */ +#define BROTLI_STATIC_INIT_LAZY 2 + +#if BROTLI_GNUC_HAS_ATTRIBUTE(constructor, 2, 7, 0) && \ + !defined(BROTLI_EXTERNAL_DICTIONARY_DATA) +#define BROTLI_STATIC_INIT_DEFAULT BROTLI_STATIC_INIT_EARLY +#else +#define BROTLI_STATIC_INIT_DEFAULT BROTLI_STATIC_INIT_NONE +#endif + +#if !defined(BROTLI_STATIC_INIT) +#define BROTLI_STATIC_INIT BROTLI_STATIC_INIT_DEFAULT +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) && \ + (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_EARLY) && \ + (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_LAZY) +#error Invalid value for BROTLI_STATIC_INIT +#endif + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) +#if defined(BROTLI_EXTERNAL_DICTIONARY_DATA) +#error BROTLI_STATIC_INIT_EARLY will fail with BROTLI_EXTERNAL_DICTIONARY_DATA +#endif +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +BROTLI_INTERNAL void BrotliEncoderLazyStaticInitInner(void); +/* This function is not provided by library. Embedder is responsible for + providing it. This function should call `BrotliEncoderLazyStaticInitInner` on + the first invocation. This function should not return until execution of + `BrotliEncoderLazyStaticInitInner` is finished. In C or before C++11 it is + possible to call `BrotliEncoderLazyStaticInitInner` on start-up path and then + `BrotliEncoderLazyStaticInit` is no-op; another option is to use available + thread execution controls to meet the requirements. + For possible C++11 implementation see static_init_lazy.cc. + */ +BROTLI_INTERNAL void BrotliEncoderLazyStaticInit(void); +#endif /* BROTLI_STATIC_INIT */ + +BROTLI_INTERNAL BROTLI_BOOL BrotliEncoderEnsureStaticInit(void); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif // THIRD_PARTY_BROTLI_ENC_STATIC_INIT_H_
diff --git a/c/enc/static_init_lazy.cc b/c/enc/static_init_lazy.cc new file mode 100644 index 0000000..726b0de --- /dev/null +++ b/c/enc/static_init_lazy.cc
@@ -0,0 +1,9 @@ +#include "third_party/brotli/enc/static_init.h" + +void BrotliEncoderLazyStaticInit(void) { + static bool ok = [](){ + BrotliEncoderLazyStaticInit(); + return true; + }(); + if (!ok) __builtin_trap(); +}