Skip to content

Commit

Permalink
Delete the old pre-c++11 Thread implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
tgoyne committed May 14, 2024
1 parent b7e545a commit 7908b66
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 342 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

### Internals
* (bindgen) Exposing a function `app_user_as_sync_user` to cast the opposite way as `sync_user_as_app_user`. ([PR #7684](https://github.com/realm/realm-core/pull/7684) as a follow-up to [PR #7634](https://github.com/realm/realm-core/pull/7634))
* `util::Thread` no longer has any functionality other than `get_name()` and `set_name()`. Use `std::thread` instead ([PR #7696](https://github.com/realm/realm-core/pull/7696)).

----------------------------------------------

Expand Down
36 changes: 3 additions & 33 deletions src/realm/util/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
*
**************************************************************************/

#include <realm/util/thread.hpp>
#include <realm/util/backtrace.hpp>

#include <cstring>
#include <stdexcept>
#include <system_error>

#include <realm/util/thread.hpp>
#include <realm/util/backtrace.hpp>

#if !defined _WIN32
#include <unistd.h>
#endif
Expand Down Expand Up @@ -58,25 +58,6 @@
using namespace realm;
using namespace realm::util;

void Thread::join()
{
if (!m_joinable)
throw util::runtime_error("Thread is not joinable");

#ifdef _WIN32
// Returns void; error handling not possible
m_std_thread.join();
#else
void** value_ptr = nullptr; // Ignore return value
int r = pthread_join(m_id, value_ptr);
if (REALM_UNLIKELY(r != 0))
join_failed(r); // Throws
#endif

m_joinable = false;
}


void Thread::set_name(const std::string& name)
{
#if REALM_PLATFORM_APPLE
Expand Down Expand Up @@ -131,17 +112,6 @@ bool Thread::get_name(std::string& name) noexcept
}


REALM_NORETURN void Thread::create_failed(int)
{
throw std::runtime_error("pthread_create() failed");
}

REALM_NORETURN void Thread::join_failed(int)
{
// It is intentional that the argument is ignored here.
throw std::runtime_error("pthread_join() failed.");
}

void Mutex::init_as_process_shared(bool robust_if_available)
{
#ifdef REALM_HAVE_PTHREAD_PROCESS_SHARED
Expand Down
153 changes: 13 additions & 140 deletions src/realm/util/thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,68 +19,30 @@
#ifndef REALM_UTIL_THREAD_HPP
#define REALM_UTIL_THREAD_HPP

#include <realm/util/assert.hpp>
#include <realm/util/features.h>
#include <realm/util/terminate.hpp>

#include <atomic>
#include <cerrno>
#include <cstddef>
#include <exception>
#include <memory>
#include <stdexcept>
#include <string>

#ifdef _WIN32
#include <thread>
#include <condition_variable> // for windows non-interprocess condvars we use std::condition_variable
#include <thread>
#include <Windows.h>
#include <process.h> // _getpid()
#else
#include <pthread.h>
#endif

// Use below line to enable a thread bug detection tool. Note: Will make program execution slower.
// #include <../test/pthread_test.hpp>

#include <cerrno>
#include <cstddef>
#include <string>

#include <realm/util/features.h>
#include <realm/util/assert.hpp>
#include <realm/util/terminate.hpp>
#include <memory>
#include <stdexcept>

#include <atomic>

namespace realm {
namespace util {


/// A separate thread of execution.
///
/// This class is a C++03 compatible reproduction of a subset of std::thread
/// from C++11 (when discounting Thread::start(), Thread::set_name(), and
/// Thread::get_name()).
namespace realm::util {
class Thread {
public:
Thread();
~Thread() noexcept;

template <class F>
explicit Thread(F func);

// Disable copying. It is an error to copy this Thread class.
Thread(const Thread&) = delete;
Thread& operator=(const Thread&) = delete;

Thread(Thread&&) noexcept;

/// This method is an extension of the API provided by
/// std::thread. This method exists because proper move semantics
/// is unavailable in C++03. If move semantics had been available,
/// calling `start(func)` would have been equivalent to `*this =
/// Thread(func)`. Please see std::thread::operator=() for
/// details.
template <class F>
void start(F func);

bool joinable() noexcept;

void join();

// If supported by the platform, set the name of the calling thread (mainly
// for debugging purposes). The name will be silently clamped to whatever
// limit the platform places on these names. Linux places a limit of 15
Expand All @@ -91,23 +53,6 @@ class Thread {
// calling thread to \a name, and returns true, otherwise it does nothing
// and returns false.
static bool get_name(std::string& name) noexcept;

private:
#ifdef _WIN32
std::thread m_std_thread;
#else
pthread_t m_id;
#endif
bool m_joinable;
typedef void* (*entry_func_type)(void*);

void start(entry_func_type, void* arg);

template <class>
static void* entry_point(void*) noexcept;

REALM_NORETURN static void create_failed(int);
REALM_NORETURN static void join_failed(int);
};


Expand Down Expand Up @@ -411,77 +356,6 @@ class CriticalSection {

// Implementation:

inline Thread::Thread()
: m_joinable(false)
{
}

template <class F>
inline Thread::Thread(F func)
: m_joinable(true)
{
std::unique_ptr<F> func2(new F(func)); // Throws
start(&Thread::entry_point<F>, func2.get()); // Throws
func2.release();
}

inline Thread::Thread(Thread&& thread) noexcept
{
#ifndef _WIN32
m_id = thread.m_id;
m_joinable = thread.m_joinable;
thread.m_joinable = false;
#endif
}

template <class F>
inline void Thread::start(F func)
{
if (m_joinable)
std::terminate();
std::unique_ptr<F> func2(new F(func)); // Throws
start(&Thread::entry_point<F>, func2.get()); // Throws
func2.release();
m_joinable = true;
}

inline Thread::~Thread() noexcept
{
if (m_joinable)
REALM_TERMINATE("Destruction of joinable thread");
}

inline bool Thread::joinable() noexcept
{
return m_joinable;
}

inline void Thread::start(entry_func_type entry_func, void* arg)
{
#ifdef _WIN32
m_std_thread = std::thread(entry_func, arg);
#else
const pthread_attr_t* attr = nullptr; // Use default thread attributes
int r = pthread_create(&m_id, attr, entry_func, arg);
if (REALM_UNLIKELY(r != 0))
create_failed(r); // Throws
#endif
}

template <class F>
inline void* Thread::entry_point(void* cookie) noexcept
{
std::unique_ptr<F> func(static_cast<F*>(cookie));
try {
(*func)();
}
catch (...) {
std::terminate();
}
return 0;
}


inline Mutex::Mutex()
{
init_as_regular();
Expand Down Expand Up @@ -806,7 +680,6 @@ void store_atomic(T& t_ref, T value, std::memory_order order)
}


} // namespace util
} // namespace realm
} // namespace realm::util

#endif // REALM_UTIL_THREAD_HPP
18 changes: 9 additions & 9 deletions src/realm/util/thread_exec_guard.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#ifndef REALM_UTIL_THREAD_EXEC_GUARD_HPP
#define REALM_UTIL_THREAD_EXEC_GUARD_HPP

#include <exception>
#include <utility>
#include <string>

#include <realm/util/thread.hpp>
#include <realm/util/signal_blocker.hpp>
#include <realm/util/thread.hpp>

#include <exception>
#include <string>
#include <thread>
#include <utility>

namespace realm {
namespace util {
Expand Down Expand Up @@ -48,7 +48,7 @@ class ThreadExecGuard {
private:
struct State {
R& runnable;
util::Thread thread;
std::thread thread;
std::exception_ptr exception;
State(R&) noexcept;
~State() noexcept;
Expand Down Expand Up @@ -114,7 +114,7 @@ class ThreadExecGuardWithParent {
struct State {
R& runnable;
P& parent;
util::Thread thread;
std::thread thread;
std::exception_ptr exception;
State(R&, P&) noexcept;
~State() noexcept;
Expand Down Expand Up @@ -209,7 +209,7 @@ inline void ThreadExecGuard<R>::State::start(const std::string* thread_name)
exception = std::current_exception();
}
};
thread.start(std::move(run)); // Throws
thread = std::thread(std::move(run)); // Throws
}

template <class R>
Expand Down Expand Up @@ -299,7 +299,7 @@ inline void ThreadExecGuardWithParent<R, P>::State::start(const std::string* thr
parent.stop();
}
};
thread.start(std::move(run)); // Throws
thread = std::thread(std::move(run)); // Throws
}

template <class R, class P>
Expand Down
Loading

0 comments on commit 7908b66

Please sign in to comment.