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>8
namespace cheatah::thread {10
Thread::Thread(std::thread t, std::shared_ptr<detail::State> state) noexcept11
: t_(std::move(t)), state_(std::move(state)) {}13
Thread::Thread(Thread&& other) noexcept = default;15
Thread& Thread::operator=(Thread&& other) noexcept {16
if (this != &other) {17
settle(); // the old thread is joined (and an unobserved error reported) before adopting18
t_ = std::move(other.t_);19
state_ = std::move(other.state_);20
}21
return *this;22
}24
Thread::~Thread() { settle(); }26
void 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
}35
}37
bool Thread::joinable() const noexcept { return t_.joinable(); }39
void 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
}54
}56
} // namespace cheatah::thread