1919#ifndef REALM_UTIL_THREAD_HPP
2020#define REALM_UTIL_THREAD_HPP
2121
22+ #include < realm/util/assert.hpp>
23+ #include < realm/util/features.h>
24+ #include < realm/util/terminate.hpp>
25+
26+ #include < atomic>
27+ #include < cerrno>
28+ #include < cstddef>
2229#include < exception>
30+ #include < memory>
31+ #include < stdexcept>
32+ #include < string>
2333
2434#ifdef _WIN32
25- #include < thread>
2635#include < condition_variable> // for windows non-interprocess condvars we use std::condition_variable
36+ #include < thread>
2737#include < Windows.h>
2838#include < process.h> // _getpid()
2939#else
3040#include < pthread.h>
3141#endif
3242
33- // Use below line to enable a thread bug detection tool. Note: Will make program execution slower.
34- // #include <../test/pthread_test.hpp>
35-
36- #include < cerrno>
37- #include < cstddef>
38- #include < string>
39-
40- #include < realm/util/features.h>
41- #include < realm/util/assert.hpp>
42- #include < realm/util/terminate.hpp>
43- #include < memory>
44- #include < stdexcept>
45-
46- #include < atomic>
47-
48- namespace realm {
49- namespace util {
50-
51-
52- // / A separate thread of execution.
53- // /
54- // / This class is a C++03 compatible reproduction of a subset of std::thread
55- // / from C++11 (when discounting Thread::start(), Thread::set_name(), and
56- // / Thread::get_name()).
43+ namespace realm ::util {
5744class Thread {
5845public:
59- Thread ();
60- ~Thread () noexcept ;
61-
62- template <class F >
63- explicit Thread (F func);
64-
65- // Disable copying. It is an error to copy this Thread class.
66- Thread (const Thread&) = delete ;
67- Thread& operator =(const Thread&) = delete ;
68-
69- Thread (Thread&&) noexcept ;
70-
71- // / This method is an extension of the API provided by
72- // / std::thread. This method exists because proper move semantics
73- // / is unavailable in C++03. If move semantics had been available,
74- // / calling `start(func)` would have been equivalent to `*this =
75- // / Thread(func)`. Please see std::thread::operator=() for
76- // / details.
77- template <class F >
78- void start (F func);
79-
80- bool joinable () noexcept ;
81-
82- void join ();
83-
8446 // If supported by the platform, set the name of the calling thread (mainly
8547 // for debugging purposes). The name will be silently clamped to whatever
8648 // limit the platform places on these names. Linux places a limit of 15
@@ -91,23 +53,6 @@ class Thread {
9153 // calling thread to \a name, and returns true, otherwise it does nothing
9254 // and returns false.
9355 static bool get_name (std::string& name) noexcept ;
94-
95- private:
96- #ifdef _WIN32
97- std::thread m_std_thread;
98- #else
99- pthread_t m_id;
100- #endif
101- bool m_joinable;
102- typedef void * (*entry_func_type)(void *);
103-
104- void start (entry_func_type, void * arg);
105-
106- template <class >
107- static void * entry_point (void *) noexcept ;
108-
109- REALM_NORETURN static void create_failed (int );
110- REALM_NORETURN static void join_failed (int );
11156};
11257
11358
@@ -411,77 +356,6 @@ class CriticalSection {
411356
412357// Implementation:
413358
414- inline Thread::Thread ()
415- : m_joinable(false )
416- {
417- }
418-
419- template <class F >
420- inline Thread::Thread (F func)
421- : m_joinable(true )
422- {
423- std::unique_ptr<F> func2 (new F (func)); // Throws
424- start (&Thread::entry_point<F>, func2.get ()); // Throws
425- func2.release ();
426- }
427-
428- inline Thread::Thread (Thread&& thread) noexcept
429- {
430- #ifndef _WIN32
431- m_id = thread.m_id ;
432- m_joinable = thread.m_joinable ;
433- thread.m_joinable = false ;
434- #endif
435- }
436-
437- template <class F >
438- inline void Thread::start (F func)
439- {
440- if (m_joinable)
441- std::terminate ();
442- std::unique_ptr<F> func2 (new F (func)); // Throws
443- start (&Thread::entry_point<F>, func2.get ()); // Throws
444- func2.release ();
445- m_joinable = true ;
446- }
447-
448- inline Thread::~Thread () noexcept
449- {
450- if (m_joinable)
451- REALM_TERMINATE (" Destruction of joinable thread" );
452- }
453-
454- inline bool Thread::joinable () noexcept
455- {
456- return m_joinable;
457- }
458-
459- inline void Thread::start (entry_func_type entry_func, void * arg)
460- {
461- #ifdef _WIN32
462- m_std_thread = std::thread (entry_func, arg);
463- #else
464- const pthread_attr_t * attr = nullptr ; // Use default thread attributes
465- int r = pthread_create (&m_id, attr, entry_func, arg);
466- if (REALM_UNLIKELY (r != 0 ))
467- create_failed (r); // Throws
468- #endif
469- }
470-
471- template <class F >
472- inline void * Thread::entry_point (void * cookie) noexcept
473- {
474- std::unique_ptr<F> func (static_cast <F*>(cookie));
475- try {
476- (*func)();
477- }
478- catch (...) {
479- std::terminate ();
480- }
481- return 0 ;
482- }
483-
484-
485359inline Mutex::Mutex ()
486360{
487361 init_as_regular ();
@@ -806,7 +680,6 @@ void store_atomic(T& t_ref, T value, std::memory_order order)
806680}
807681
808682
809- } // namespace util
810- } // namespace realm
683+ } // namespace realm::util
811684
812685#endif // REALM_UTIL_THREAD_HPP
0 commit comments