ServiceManagerFsm wrapped a tinyfsm machine, whose state and mutex are static, so every ServiceManager in a process shared one lifecycle. One manager's construction, reset() or shutdown changed what the others saw: a failed second daemon's destructor drove the running daemon's FSM to Stopped (#357 made shutdown run anyway; readiness checks such as canBuildSearchEngine() and isReady() still read the wrong state). The FSM now keeps a snapshot, mutex and condition variable per instance. The public interface is unchanged, and the transitions match the former machine: unhandled events are ignored, InitializationFailedEvent moves a non-terminal state to Failed, and ShutdownEvent moves any state except ShuttingDown/Stopped to ShuttingDown. The FSM suite's shared-state recovery section now checks that one instance's construction, shutdown and reset leave another's state alone. Signed-off-by: trvon <me@trevon.dev>
75 lines
3.5 KiB
Text
75 lines
3.5 KiB
Text
# ThreadSanitizer suppressions for YAMS
|
|
|
|
# Boost.Asio experimental channel - known library limitation
|
|
# The channel_service uses null_mutex even when channel_traits<std::mutex> is specified
|
|
# This appears to be a boost library issue in versions < 1.85
|
|
race:boost::asio::experimental::detail::channel_service
|
|
race:channel_service.hpp
|
|
|
|
# Boost.Asio thread_info_base - thread-local storage cleanup race
|
|
# This is an internal boost::asio issue during thread destruction
|
|
race:boost::asio::detail::thread_info_base::deallocate
|
|
|
|
# Boost.Asio executor - internal race during coroutine dispatch
|
|
# This appears to be a timing issue in boost::asio's any_executor
|
|
race:boost::asio::execution::detail::any_executor_base::execute
|
|
race:any_executor.hpp
|
|
|
|
# Boost.Asio kqueue reactor descriptor mutex - upstream TSAN false positive when
|
|
# conditionally_enabled_mutex is reinitialized out of line with the reactor run
|
|
# loop (tracked upstream for Boost.Asio kqueue).
|
|
race:boost::asio::detail::conditionally_enabled_mutex
|
|
race:boost::asio::detail::conditionally_enabled_mutex::scoped_lock
|
|
race:conditionally_enabled_mutex.hpp
|
|
race:kqueue_reactor.ipp
|
|
race:kqueue_reactor.hpp
|
|
race:boost::asio::detail::kqueue_reactor::descriptor_state
|
|
race:boost::asio::detail::kqueue_reactor::allocate_descriptor_state
|
|
race:boost::asio::detail::kqueue_reactor::register_descriptor
|
|
race:boost::asio::detail::kqueue_reactor::run
|
|
race:object_pool.hpp
|
|
|
|
# Boost.Asio reactive socket service - race in socket descriptor registration
|
|
# when sockets are constructed/moved across threads. The reactor's internal
|
|
# fd_set_ tracking has a data race in reactive_socket_service_base::construct().
|
|
# This is a known boost::asio internal issue.
|
|
race:boost::asio::detail::reactive_socket_service_base::construct
|
|
race:boost::asio::detail::reactive_socket_service_base::do_assign
|
|
race:reactive_socket_service_base.ipp
|
|
race:reactive_socket_accept_op.hpp
|
|
|
|
# Boost.Asio strand destructor - mutex use-after-free during complex shutdown
|
|
# When ServiceManager is destroyed, pending async operations may still hold
|
|
# references to the strand's executor. This is a destruction order issue
|
|
# in complex coroutine-based shutdown sequences.
|
|
mutex:boost::asio::strand
|
|
mutex:boost::asio::detail::posix_mutex
|
|
mutex:boost::asio::detail::strand_executor_service
|
|
|
|
race:TuningManager
|
|
race:unique_ptr*TuningManager
|
|
|
|
# tinyfsm uses CRTP static state per Fsm class, so concurrent construction
|
|
# of multiple YamsDaemon instances in the same process (test-only scenario)
|
|
# races on the static snapshot/entry storage. Production has one daemon
|
|
# per process; the race cannot occur there.
|
|
race:yams::daemon::detail::LifecycleMachine
|
|
race:yams::daemon::detail::PluginHostMachine
|
|
race:yams::daemon::detail::EmbeddingProviderMachine
|
|
race:yams::daemon::detail::SearchEngineMachine
|
|
race:yams::daemon::LifecycleSnapshot
|
|
race:yams::daemon::ProviderSnapshot
|
|
race:yams::daemon::PluginHostSnapshot
|
|
race:yams::daemon::SearchEngineSnapshot
|
|
race:yams::daemon::ServiceManagerSnapshot
|
|
|
|
# gcc TSan does not model a standalone std::atomic_thread_fence. asio's executor refcount
|
|
# drops with fetch_sub(release) and then fences acquire before the last delete, so gcc reports
|
|
# the delete as racing the other thread's decrement. clang does not report it.
|
|
race:boost::asio::detail::ref_count_down
|
|
|
|
# SQLite reads and writes the WAL-index header in the -shm mapping without locks: double copy,
|
|
# memory barrier, checksum, retry. SQLite marks both functions SQLITE_NO_TSAN, which is defined
|
|
# for clang only, so gcc reports races between separate connections on the same database.
|
|
race:walIndexTryHdr
|
|
race:walIndexWriteHdr
|