/*----------------------------------------------------------------------------*/ /* Copyright (c) 2015-2018 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ /*----------------------------------------------------------------------------*/ #include "wpi/SafeThread.h" using namespace wpi; detail::SafeThreadProxyBase::SafeThreadProxyBase( std::shared_ptr thr) : m_thread(std::move(thr)) { if (!m_thread) return; m_lock = std::unique_lock(m_thread->m_mutex); if (!m_thread->m_active) { m_lock.unlock(); m_thread = nullptr; return; } } void detail::SafeThreadOwnerBase::Start(std::shared_ptr thr) { std::lock_guard lock(m_mutex); if (auto thr = m_thread.lock()) return; std::thread stdThread([=] { thr->Main(); }); m_thread = thr; m_nativeHandle = stdThread.native_handle(); stdThread.detach(); } void detail::SafeThreadOwnerBase::Stop() { std::lock_guard lock(m_mutex); if (auto thr = m_thread.lock()) { thr->m_active = false; thr->m_cond.notify_one(); } } void detail::swap(SafeThreadOwnerBase& lhs, SafeThreadOwnerBase& rhs) noexcept { using std::swap; if (&lhs == &rhs) return; std::lock(lhs.m_mutex, rhs.m_mutex); std::lock_guard lock_lhs(lhs.m_mutex, std::adopt_lock); std::lock_guard lock_rhs(rhs.m_mutex, std::adopt_lock); std::swap(lhs.m_thread, rhs.m_thread); std::swap(lhs.m_nativeHandle, rhs.m_nativeHandle); } detail::SafeThreadOwnerBase::operator bool() const { std::lock_guard lock(m_mutex); return !m_thread.expired(); } std::thread::native_handle_type detail::SafeThreadOwnerBase::GetNativeThreadHandle() const { std::lock_guard lock(m_mutex); return m_nativeHandle; } std::shared_ptr detail::SafeThreadOwnerBase::GetThread() const { std::lock_guard lock(m_mutex); return m_thread.lock(); }