cheatah
Source

stdlib/thread/thread.cpp

1// Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
2// Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
3#include "thread.hpp"
5#include <iostream>
6#include <stdexcept>
8namespace cheatah::thread {
10Thread::Thread(std::thread t, std::shared_ptr<detail::State> state) noexcept
11 : t_(std::move(t)), state_(std::move(state)) {}
13Thread::Thread(Thread&& other) noexcept = default;
15Thread& Thread::operator=(Thread&& other) noexcept {
16 if (this != &other) {
17 settle(); // the old thread is joined (and an unobserved error reported) before adopting
18 t_ = std::move(other.t_);
19 state_ = std::move(other.state_);
20 }
21 return *this;
24Thread::~Thread() { settle(); }
26void Thread::join() {
27 if (!t_.joinable()) {
28 throw std::runtime_error("thread.join: nothing to join (already joined or moved away)");
29 }
30 t_.join();
31 if (state_ && state_->error) {
32 state_->observed = true;
33 std::rethrow_exception(state_->error);
34 }
37bool Thread::joinable() const noexcept { return t_.joinable(); }
39void Thread::settle() noexcept {
40 if (t_.joinable()) t_.join();
41 if (state_ && state_->error && !state_->observed) {
42 state_->observed = true;
43 // A destructor must not throw, so an exception nobody joined for is REPORTED, not lost —
44 // the analogue of Python's default excepthook for a thread.
45 std::string what = "unknown error";
46 try {
47 std::rethrow_exception(state_->error);
48 } catch (const std::exception& e) {
49 what = e.what();
50 } catch (...) {
51 }
52 std::cerr << "cheatah thread: unhandled exception in thread: " << what << "\n";
53 }
56} // namespace cheatah::thread