I'm running into a warning from ThreadSanitizer while using `sqlite3_enable_shared_cache()` between two threads. I've minimized it down to a simple test program below, followed by the back trace from TSan. ``` #include <chrono> #include <thread> #include <sqlite3.h> namespace { void Init() { sqlite3_enable_shared_cache(1); std::this_thread::sleep_for(std::chrono::seconds(2)); } } // namespace int main(int argc, char* argv[]) { std::thread t1(&Init); std::thread t2(&Init); t1.join(); t2.join(); return 0; } ``` With that file in `test.cc` and `sqlite3.{h,c}` in the same directory, I'm building with: ``` clang-11 -fsanitize=thread -g -c sqlite3.c clang-11 -std=c++17 -stdlib=libstdc++ -fsanitize=thread -g -I. -c test.cc clang -lstdc++ -std=c++17 -fsanitize=thread *.o -o warn_test ``` Running `warn_test` results in this report from TSan: ``` ================== WARNING: ThreadSanitizer: data race (pid=123110) Write of size 4 at 0x000000706dac by thread T2: #0 sqlite3_enable_shared_cache /home/tim/test/sqlite3.c:65571:3 (race+0x4c3d8a) #1 (anonymous namespace)::Init() /home/tim/test/test.cc:12:2 (race+0x6a35ea) #2 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h:60:14 (race+0x6a49ed) #3 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h:95:14 (race+0x6a48f0) #4 void std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:244:13 (race+0x6a4898) #5 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:251:11 (race+0x6a4838) #6 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:195:13 (race+0x6a461f) #7 <null> <null> (libstdc++.so.6+0xd6de3) Previous write of size 4 at 0x000000706dac by thread T1: #0 sqlite3_enable_shared_cache /home/tim/test/sqlite3.c:65571:3 (race+0x4c3d8a) #1 (anonymous namespace)::Init() /home/tim/test/test.cc:12:2 (race+0x6a35ea) #2 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h:60:14 (race+0x6a49ed) #3 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h:95:14 (race+0x6a48f0) #4 void std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:244:13 (race+0x6a4898) #5 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:251:11 (race+0x6a4838) #6 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/thread:195:13 (race+0x6a461f) #7 <null> <null> (libstdc++.so.6+0xd6de3) Location is global 'sqlite3Config' of size 424 at 0x000000706c60 (race+0x000000706dac) Thread T2 (tid=123113, running) created by main thread at: #0 pthread_create <null> (race+0x425ccb) #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd70a8) #2 main /home/tim/test/test.cc:20:14 (race+0x6a34d1) Thread T1 (tid=123112, running) created by main thread at: #0 pthread_create <null> (race+0x425ccb) #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) <null> (libstdc++.so.6+0xd70a8) #2 main /home/tim/test/test.cc:19:14 (race+0x6a34a7) SUMMARY: ThreadSanitizer: data race /home/tim/test/sqlite3.c:65571:3 in sqlite3_enable_shared_cache ================== ThreadSanitizer: reported 1 warnings ``` I'm able to fix it by changing `sqlite3GlobalConfig.sharedCacheEnabled` to be an `atomic_int` and #include'ing `<stdatomic.h>` but I understand that's a C11 feature and may not be acceptable. I did try to fix it using `AtomicLoad()` and `AtomicStore()` but for some reason I was getting the same warning from TSan.