Thread safe crc32 table initialization

The lazy generated table was not entirely thread safe under the
C++ (11) memory model, as pointed out by TSAN.

Bug: webrtc:10627
Change-Id: I0fe1cc7c10ca218a92c710a6382b64d7827f3a6a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/136980
Reviewed-by: Amit Hilbuch <amithi@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27954}
diff --git a/rtc_base/crc32.cc b/rtc_base/crc32.cc
index c70f5fe..42f86cb 100644
--- a/rtc_base/crc32.cc
+++ b/rtc_base/crc32.cc
@@ -19,11 +19,9 @@
 // CRC32 polynomial, in reversed form.
 // See RFC 1952, or http://en.wikipedia.org/wiki/Cyclic_redundancy_check
 static const uint32_t kCrc32Polynomial = 0xEDB88320;
-static uint32_t kCrc32Table[256] = {0};
 
-static void EnsureCrc32TableInited() {
-  if (kCrc32Table[arraysize(kCrc32Table) - 1])
-    return;  // already inited
+static uint32_t* LoadCrc32Table() {
+  static uint32_t kCrc32Table[256];
   for (uint32_t i = 0; i < arraysize(kCrc32Table); ++i) {
     uint32_t c = i;
     for (size_t j = 0; j < 8; ++j) {
@@ -35,10 +33,11 @@
     }
     kCrc32Table[i] = c;
   }
+  return kCrc32Table;
 }
 
 uint32_t UpdateCrc32(uint32_t start, const void* buf, size_t len) {
-  EnsureCrc32TableInited();
+  static uint32_t* kCrc32Table = LoadCrc32Table();
 
   uint32_t c = start ^ 0xFFFFFFFF;
   const uint8_t* u = static_cast<const uint8_t*>(buf);