1// LAF Base Library
2// Copyright (C) 2019-2021 Igara Studio S.A.
3// Copyright (C) 2001-2016 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef BASE_THREAD_H_INCLUDED
9#define BASE_THREAD_H_INCLUDED
10#pragma once
11
12#if LAF_WINDOWS
13 #include "base/ints.h"
14#endif
15
16namespace base { // Based on C++0x threads lib
17
18 class thread {
19 public:
20 typedef void* native_handle_type;
21#if LAF_WINDOWS
22 typedef uint32_t native_id_type;
23#else
24 typedef void* native_id_type;
25#endif
26
27 // Create an instance to represent the current thread
28 thread();
29
30 // Create a new thread without arguments
31 template<class Callable>
32 thread(const Callable& f) {
33 launch_thread(new func_wrapper0<Callable>(f));
34 }
35
36 // Create a new thread with one argument
37 template<class Callable, class A>
38 thread(const Callable& f, A a) {
39 launch_thread(new func_wrapper1<Callable, A>(f, a));
40 }
41
42 // Create a new thread with two arguments
43 template<class Callable, class A, class B>
44 thread(const Callable& f, A a, B b) {
45 launch_thread(new func_wrapper2<Callable, A, B>(f, a, b));
46 }
47
48 ~thread();
49
50 bool joinable() const;
51 void join();
52 void detach();
53
54 native_id_type native_id() const;
55
56 class details {
57 public:
58 static void thread_proxy(void* data);
59 };
60
61 private:
62 native_handle_type m_native_handle;
63#if LAF_WINDOWS
64 native_id_type m_native_id;
65#endif
66
67 class func_wrapper {
68 public:
69 virtual ~func_wrapper() { }
70 virtual void operator()() = 0;
71 };
72
73 void launch_thread(func_wrapper* f);
74
75 template<class Callable>
76 class func_wrapper0 : public func_wrapper {
77 public:
78 Callable f;
79 func_wrapper0(const Callable& f) : f(f) { }
80 void operator()() { f(); }
81 };
82
83 template<class Callable, class A>
84 class func_wrapper1 : public func_wrapper {
85 public:
86 Callable f;
87 A a;
88 func_wrapper1(const Callable& f, A a) : f(f), a(a) { }
89 void operator()() { f(a); }
90 };
91
92 template<class Callable, class A, class B>
93 class func_wrapper2 : public func_wrapper {
94 public:
95 Callable f;
96 A a;
97 B b;
98 func_wrapper2(const Callable& f, A a, B b) : f(f), a(a), b(b) { }
99 void operator()() { f(a, b); }
100 };
101
102 };
103
104 namespace this_thread
105 {
106 void yield();
107 void sleep_for(double seconds);
108 thread::native_id_type native_id();
109 }
110
111 // This class joins the thread in its destructor.
112 class thread_guard {
113 thread& m_thread;
114 public:
115 explicit thread_guard(thread& t) : m_thread(t) { }
116 ~thread_guard()
117 {
118 if (m_thread.joinable())
119 m_thread.join();
120 }
121 };
122
123}
124
125#endif
126