WPILibC++ 2024.3.2
SafeThread.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#ifndef WPIUTIL_WPI_SAFETHREAD_H_
6#define WPIUTIL_WPI_SAFETHREAD_H_
7
8#include <atomic>
9#include <memory>
10#include <thread>
11#include <utility>
12
13#include "wpi/Synchronization.h"
15#include "wpi/mutex.h"
16
17namespace wpi {
18
19/**
20 * Base class for SafeThreadOwner threads.
21 */
23 public:
24 virtual ~SafeThreadBase() = default;
25 virtual void Main() = 0;
26 virtual void Stop() = 0;
27
29 std::atomic_bool m_active{true};
30 std::thread::id m_threadId;
31};
32
33class SafeThread : public SafeThreadBase {
34 public:
35 void Stop() override;
36
38};
39
41 public:
43
44 void Stop() override;
45
47};
48
49namespace detail {
50
51/**
52 * Non-template proxy base class for common proxy code.
53 */
55 public:
56 explicit SafeThreadProxyBase(std::shared_ptr<SafeThreadBase> thr);
57 explicit operator bool() const { return m_thread != nullptr; }
58 std::unique_lock<wpi::mutex>& GetLock() { return m_lock; }
59
60 protected:
61 std::shared_ptr<SafeThreadBase> m_thread;
62 std::unique_lock<wpi::mutex> m_lock;
63};
64
65/**
66 * A proxy for SafeThread.
67 *
68 * Also serves as a scoped lock on SafeThread::m_mutex.
69 */
70template <typename T>
72 public:
73 explicit SafeThreadProxy(std::shared_ptr<SafeThreadBase> thr)
74 : SafeThreadProxyBase(std::move(thr)) {}
75 T& operator*() const { return *static_cast<T*>(m_thread.get()); }
76 T* operator->() const { return static_cast<T*>(m_thread.get()); }
77};
78
79/**
80 * Non-template owner base class for common owner code.
81 */
83 public:
84 void Stop();
85 void Join();
86
87 SafeThreadOwnerBase() noexcept = default;
89 SafeThreadOwnerBase& operator=(const SafeThreadOwnerBase&) = delete;
92 swap(*this, other);
93 }
95 swap(*this, other);
96 return *this;
97 }
99
100 friend void swap(SafeThreadOwnerBase& lhs, SafeThreadOwnerBase& rhs) noexcept;
101
102 explicit operator bool() const;
103
104 std::thread::native_handle_type GetNativeThreadHandle();
105
106 void SetJoinAtExit(bool joinAtExit) { m_joinAtExit = joinAtExit; }
107
108 protected:
109 void Start(std::shared_ptr<SafeThreadBase> thr);
110 std::shared_ptr<SafeThreadBase> GetThreadSharedPtr() const;
111
112 private:
113 mutable wpi::mutex m_mutex;
114 std::thread m_stdThread;
115 std::weak_ptr<SafeThreadBase> m_thread;
116 std::atomic_bool m_joinAtExit{true};
117};
118
120
121} // namespace detail
122
123template <typename T>
125 public:
126 template <typename... Args>
127 void Start(Args&&... args) {
129 std::make_shared<T>(std::forward<Args>(args)...));
130 }
131
133 Proxy GetThread() const {
135 }
136
137 std::shared_ptr<T> GetThreadSharedPtr() const {
138 return std::static_pointer_cast<T>(
140 }
141};
142
143} // namespace wpi
144
145#endif // WPIUTIL_WPI_SAFETHREAD_H_
An atomic signaling event for synchronization.
Definition: Synchronization.h:250
Base class for SafeThreadOwner threads.
Definition: SafeThread.h:22
virtual void Main()=0
virtual void Stop()=0
virtual ~SafeThreadBase()=default
std::thread::id m_threadId
Definition: SafeThread.h:30
std::atomic_bool m_active
Definition: SafeThread.h:29
wpi::mutex m_mutex
Definition: SafeThread.h:28
Definition: SafeThread.h:40
SafeThreadEvent()
Definition: SafeThread.h:42
Event m_stopEvent
Definition: SafeThread.h:46
void Stop() override
Definition: SafeThread.h:33
void Stop() override
wpi::condition_variable m_cond
Definition: SafeThread.h:37
Definition: SafeThread.h:124
void Start(Args &&... args)
Definition: SafeThread.h:127
Proxy GetThread() const
Definition: SafeThread.h:133
typename detail::SafeThreadProxy< T > Proxy
Definition: SafeThread.h:132
std::shared_ptr< T > GetThreadSharedPtr() const
Definition: SafeThread.h:137
Non-template owner base class for common owner code.
Definition: SafeThread.h:82
void SetJoinAtExit(bool joinAtExit)
Definition: SafeThread.h:106
void Start(std::shared_ptr< SafeThreadBase > thr)
SafeThreadOwnerBase & operator=(SafeThreadOwnerBase &&other) noexcept
Definition: SafeThread.h:94
SafeThreadOwnerBase() noexcept=default
friend void swap(SafeThreadOwnerBase &lhs, SafeThreadOwnerBase &rhs) noexcept
std::thread::native_handle_type GetNativeThreadHandle()
std::shared_ptr< SafeThreadBase > GetThreadSharedPtr() const
Non-template proxy base class for common proxy code.
Definition: SafeThread.h:54
std::unique_lock< wpi::mutex > & GetLock()
Definition: SafeThread.h:58
std::shared_ptr< SafeThreadBase > m_thread
Definition: SafeThread.h:61
SafeThreadProxyBase(std::shared_ptr< SafeThreadBase > thr)
std::unique_lock< wpi::mutex > m_lock
Definition: SafeThread.h:62
A proxy for SafeThread.
Definition: SafeThread.h:71
T * operator->() const
Definition: SafeThread.h:76
SafeThreadProxy(std::shared_ptr< SafeThreadBase > thr)
Definition: SafeThread.h:73
T & operator*() const
Definition: SafeThread.h:75
detail namespace with internal helper functions
Definition: xchar.h:20
Definition: array.h:89
void swap(SafeThreadOwnerBase &lhs, SafeThreadOwnerBase &rhs) noexcept
Definition: ntcore_cpp.h:26
::std::condition_variable condition_variable
Definition: condition_variable.h:16
::std::mutex mutex
Definition: mutex.h:17