Repository: flutter
Issue: Data race in MessageLoopTaskQueues disposal.
Labels: engine,from: sanitizer,P2,team-engine,triaged-engine

Caught by thread sanitizer in `embedder_unittests`.

```
WARNING: ThreadSanitizer: data race (pid=58113)
  Write of size 8 at 0x7b0c00006e90 by main thread (mutexes: write M976290527882352256):
    #0 operator delete(void*) <null> (libclang_rt.tsan_osx_dynamic.dylib:x86_64+0x6cbd5)
    #1 std::__1::_DeallocateCaller::__do_call(void*) new:340 (embedder_unittests:x86_64+0x100008b66)
    #2 std::__1::_DeallocateCaller::__do_deallocate_handle_size(void*, unsigned long) new:298 (embedder_unittests:x86_64+0x100008b02)
    #3 std::__1::_DeallocateCaller::__do_deallocate_handle_size_align(void*, unsigned long, unsigned long) new:268 (embedder_unittests:x86_64+0x100008a92)
    #4 std::__1::__libcpp_deallocate(void*, unsigned long, unsigned long) new:346 (embedder_unittests:x86_64+0x100008a16)
    #5 std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, void*> >::deallocate(std::__1::__tree_node<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, void*>*, unsigned long) memory:1803 (embedder_unittests:x86_64+0x100e7c348)
    #6 std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, void*> > >::deallocate(std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, void*> >&, std::__1::__tree_node<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, void*>*, unsigned long) memory:1557 (embedder_unittests:x86_64+0x100e7bee6)
    #7 std::__1::__tree<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::__map_value_compare<fml::TaskQueueId, std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::less<fml::TaskQueueId>, true>, std::__1::allocator<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > > > >::erase(std::__1::__tree_const_iterator<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::__tree_node<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, void*>*, long>) __tree:2577 (embedder_unittests:x86_64+0x100e889f9)
    #8 unsigned long std::__1::__tree<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::__map_value_compare<fml::TaskQueueId, std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::less<fml::TaskQueueId>, true>, std::__1::allocator<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > > > >::__erase_unique<fml::TaskQueueId>(fml::TaskQueueId const&) __tree:2598 (embedder_unittests:x86_64+0x100e88678)
    #9 std::__1::map<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> >, std::__1::less<fml::TaskQueueId>, std::__1::allocator<std::__1::pair<fml::TaskQueueId const, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > > > >::erase(fml::TaskQueueId const&) map:1292 (embedder_unittests:x86_64+0x100e752e6)
    #10 fml::MessageLoopTaskQueues::Dispose(fml::TaskQueueId) message_loop_task_queues.cc:58 (embedder_unittests:x86_64+0x100e74ed3)
    #11 fml::MessageLoopImpl::~MessageLoopImpl() message_loop_impl.cc:50 (embedder_unittests:x86_64+0x100e724bd)
    #12 fml::MessageLoopDarwin::~MessageLoopDarwin() message_loop_darwin.mm:37 (embedder_unittests:x86_64+0x100ea4430)
    #13 fml::MessageLoopDarwin::~MessageLoopDarwin() message_loop_darwin.mm:34 (embedder_unittests:x86_64+0x100ea44e6)
    #14 fml::MessageLoopDarwin::~MessageLoopDarwin() message_loop_darwin.mm:34 (embedder_unittests:x86_64+0x100ea454a)
    #15 fml::RefCountedThreadSafe<fml::MessageLoopImpl>::Release() const ref_counted.h:73 (embedder_unittests:x86_64+0x10026b5f4)
    #16 fml::RefPtr<fml::MessageLoopImpl>::~RefPtr() ref_ptr.h:104 (embedder_unittests:x86_64+0x10026b53a)
    #17 fml::RefPtr<fml::MessageLoopImpl>::~RefPtr() ref_ptr.h:102 (embedder_unittests:x86_64+0x1002688f6)
    #18 fml::TaskRunner::~TaskRunner() task_runner.cc:21 (embedder_unittests:x86_64+0x100e9a43c)
    #19 fml::TaskRunner::~TaskRunner() task_runner.cc:21 (embedder_unittests:x86_64+0x100e9a516)
    #20 fml::TaskRunner::~TaskRunner() task_runner.cc:21 (embedder_unittests:x86_64+0x100e9a57a)
    #21 fml::RefCountedThreadSafe<fml::TaskRunner>::Release() const ref_counted.h:73 (embedder_unittests:x86_64+0x100051174)
    #22 fml::RefPtr<fml::TaskRunner>::~RefPtr() ref_ptr.h:104 (embedder_unittests:x86_64+0x1000510ba)
    #23 fml::RefPtr<fml::TaskRunner>::~RefPtr() ref_ptr.h:102 (embedder_unittests:x86_64+0x100050046)
    #24 fml::Thread::~Thread() thread.cc:42 (embedder_unittests:x86_64+0x100e9b37a)
    #25 fml::Thread::~Thread() thread.cc:40 (embedder_unittests:x86_64+0x100e9b4e6)
    #26 std::__1::default_delete<fml::Thread>::operator()(fml::Thread*) const memory:2325 (embedder_unittests:x86_64+0x100050dc4)
    #27 std::__1::unique_ptr<fml::Thread, std::__1::default_delete<fml::Thread> >::reset(fml::Thread*) memory:2638 (embedder_unittests:x86_64+0x100050c5b)
    #28 std::__1::unique_ptr<fml::Thread, std::__1::default_delete<fml::Thread> >::~unique_ptr() memory:2592 (embedder_unittests:x86_64+0x100050b7a)
    #29 std::__1::unique_ptr<fml::Thread, std::__1::default_delete<fml::Thread> >::~unique_ptr() memory:2592 (embedder_unittests:x86_64+0x100050b16)
    #30 flutter::ThreadHost::~ThreadHost() thread_host.cc:31 (embedder_unittests:x86_64+0x1021c39d4)
    #31 flutter::ThreadHost::~ThreadHost() thread_host.cc:31 (embedder_unittests:x86_64+0x1021c3a56)
    #32 flutter::EmbedderThreadHost::~EmbedderThreadHost() embedder_thread_host.cc:188 (embedder_unittests:x86_64+0x10027302d)
    #33 flutter::EmbedderThreadHost::~EmbedderThreadHost() embedder_thread_host.cc:188 (embedder_unittests:x86_64+0x1002730f6)
    #34 std::__1::default_delete<flutter::EmbedderThreadHost>::operator()(flutter::EmbedderThreadHost*) const memory:2325 (embedder_unittests:x86_64+0x100217fb4)
    #35 std::__1::unique_ptr<flutter::EmbedderThreadHost, std::__1::default_delete<flutter::EmbedderThreadHost> >::reset(flutter::EmbedderThreadHost*) memory:2638 (embedder_unittests:x86_64+0x100217e4b)
    #36 std::__1::unique_ptr<flutter::EmbedderThreadHost, std::__1::default_delete<flutter::EmbedderThreadHost> >::~unique_ptr() memory:2592 (embedder_unittests:x86_64+0x100217d6a)
    #37 std::__1::unique_ptr<flutter::EmbedderThreadHost, std::__1::default_delete<flutter::EmbedderThreadHost> >::~unique_ptr() memory:2592 (embedder_unittests:x86_64+0x10019b1d6)
    #38 flutter::EmbedderEngine::~EmbedderEngine() embedder_engine.cc:34 (embedder_unittests:x86_64+0x100224fed)
    #39 flutter::EmbedderEngine::~EmbedderEngine() embedder_engine.cc:34 (embedder_unittests:x86_64+0x1002250b6)
    #40 FlutterEngineShutdown embedder.cc:907 (embedder_unittests:x86_64+0x10019b594)
    #41 flutter::testing::UniqueEngineTraits::Free(_FlutterEngine*&) embedder_config_builder.h:24 (embedder_unittests:x86_64+0x10001e101)
    #42 fml::UniqueObject<_FlutterEngine*, flutter::testing::UniqueEngineTraits>::FreeIfNecessary() unique_object.h:101 (embedder_unittests:x86_64+0x10001e016)
    #43 fml::UniqueObject<_FlutterEngine*, flutter::testing::UniqueEngineTraits>::~UniqueObject() unique_object.h:55 (embedder_unittests:x86_64+0x10001df86)
    #44 fml::UniqueObject<_FlutterEngine*, flutter::testing::UniqueEngineTraits>::~UniqueObject() unique_object.h:55 (embedder_unittests:x86_64+0x1000041d6)
    #45 flutter::testing::EmbedderTest_CanReloadSystemFonts_Test::TestBody() embedder_unittests.cc:248 (embedder_unittests:x86_64+0x100079fbf)
    #46 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2447 (embedder_unittests:x86_64+0x103211ea4)
    #47 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2502 (embedder_unittests:x86_64+0x1031d918e)
    #48 testing::Test::Run() gtest.cc:2522 (embedder_unittests:x86_64+0x1031d9057)
    #49 testing::TestInfo::Run() gtest.cc:2698 (embedder_unittests:x86_64+0x1031da2f9)
    #50 testing::TestSuite::Run() gtest.cc:2828 (embedder_unittests:x86_64+0x1031dba30)
    #51 testing::internal::UnitTestImpl::RunAllTests() gtest.cc:5285 (embedder_unittests:x86_64+0x1031e9d07)
    #52 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2447 (embedder_unittests:x86_64+0x10321b7f4)
    #53 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2502 (embedder_unittests:x86_64+0x1031e965e)
    #54 testing::UnitTest::Run() gtest.cc:4873 (embedder_unittests:x86_64+0x1031e9456)
    #55 RUN_ALL_TESTS() gtest.h:2453 (embedder_unittests:x86_64+0x10302b2cb)
    #56 main run_all_unittests.cc:9 (embedder_unittests:x86_64+0x10302b26b)

  Previous read of size 8 at 0x7b0c00006e90 by thread T39 (mutexes: write M973757253091900288):
    #0 fml::TaskQueueId::operator int() const message_loop_task_queues.h:28 (embedder_unittests:x86_64+0x100e6a6d0)
    #1 std::__1::less<fml::TaskQueueId>::operator()(fml::TaskQueueId const&, fml::TaskQueueId const&) const __functional_base:55 (embedder_unittests:x86_64+0x100e81afa)
    #2 std::__1::__map_value_compare<fml::TaskQueueId, std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::less<fml::TaskQueueId>, true>::operator()(fml::TaskQueueId const&, std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > > const&) const map:512 (embedder_unittests:x86_64+0x100e81861)
    #3 std::__1::__tree_node_base<void*>*& std::__1::__tree<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::__map_value_compare<fml::TaskQueueId, std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::less<fml::TaskQueueId>, true>, std::__1::allocator<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > > > >::__find_equal<fml::TaskQueueId>(std::__1::__tree_end_node<std::__1::__tree_node_base<void*>*>*&, fml::TaskQueueId const&) __tree:2048 (embedder_unittests:x86_64+0x100e80d9b)
    #4 std::__1::__tree_node_base<void*>*& std::__1::__tree<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::__map_value_compare<fml::TaskQueueId, std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > >, std::__1::less<fml::TaskQueueId>, true>, std::__1::allocator<std::__1::__value_type<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > > > >::__find_equal<fml::TaskQueueId>(std::__1::__tree_end_node<std::__1::__tree_node_base<void*>*>*&, fml::TaskQueueId const&) const __tree:1476 (embedder_unittests:x86_64+0x100e8e406)
    #5 std::__1::map<fml::TaskQueueId, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> >, std::__1::less<fml::TaskQueueId>, std::__1::allocator<std::__1::pair<fml::TaskQueueId const, std::__1::unique_ptr<fml::TaskQueueEntry, std::__1::default_delete<fml::TaskQueueEntry> > > > >::at(fml::TaskQueueId const&) const map:1542 (embedder_unittests:x86_64+0x100e76a8a)
    #6 fml::MessageLoopTaskQueues::GetObserversToNotify(fml::TaskQueueId) const message_loop_task_queues.cc:179 (embedder_unittests:x86_64+0x100e77345)
    #7 fml::MessageLoopImpl::FlushTasks(fml::FlushType) message_loop_impl.cc:123 (embedder_unittests:x86_64+0x100e73349)
    #8 fml::MessageLoopImpl::RunExpiredTasksNow() message_loop_impl.cc:131 (embedder_unittests:x86_64+0x100e730db)
    #9 fml::MessageLoopDarwin::OnTimerFire(__CFRunLoopTimer*, fml::MessageLoopDarwin*) message_loop_darwin.mm:75 (embedder_unittests:x86_64+0x100ea412b)
    #10 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ <null> (CoreFoundation:x86_64h+0x5a05f)
    #11 fml::MessageLoopImpl::DoRun() message_loop_impl.cc:90 (embedder_unittests:x86_64+0x100e72f87)
    #12 fml::MessageLoop::Run() message_loop.cc:49 (embedder_unittests:x86_64+0x100e712ce)
    #13 fml::Thread::Thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0::operator()() const thread.cc:34 (embedder_unittests:x86_64+0x100e9ce1e)
    #14 decltype(std::__1::forward<fml::Thread::Thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0>(fp)()) std::__1::__invoke<fml::Thread::Thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0>(fml::Thread::Thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0&&) type_traits:4350 (embedder_unittests:x86_64+0x100e9cc5e)
    #15 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, fml::Thread::Thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, fml::Thread::Thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0>&, std::__1::__tuple_indices<>) thread:342 (embedder_unittests:x86_64+0x100e9cb16)
    #16 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, fml::Thread::Thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0> >(void*) thread:352 (embedder_unittests:x86_64+0x100e9c1e4)

```