1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#include <atomic>
#include "Exceptions.h"
#include "Threads.h"
#include "Local.h"
#include "TaskMan.h"
namespace Balau {
class ThreadHelper {
public:
static void * threadProc(void * arg);
};
}
Balau::Lock::Lock() {
int r;
pthread_mutexattr_t attr;
r = pthread_mutexattr_init(&attr);
RAssert(r == 0, "Couldn't initialize mutex attribute; r = %i", r);
r = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
RAssert(r == 0, "Couldn't set mutex attribute; r = %i", r);
r = pthread_mutex_init(&m_lock, &attr);
RAssert(r == 0, "Couldn't initialize mutex; r = %i", r);
r = pthread_mutexattr_destroy(&attr);
RAssert(r == 0, "Couldn't destroy mutex attribute; r = %i", r);
}
Balau::RWLock::RWLock() {
int r;
r = pthread_rwlock_init(&m_lock, NULL);
RAssert(r == 0, "Couldn't initialize read write lock; r = %i", r);
}
void * Balau::ThreadHelper::threadProc(void * arg) {
void * r = NULL;
bool success = false;
try {
void * tls = Local::createTLS();
g_tlsManager->setTLS(tls);
Balau::Thread * thread = reinterpret_cast<Balau::Thread *>(arg);
r = thread->proc();
free(tls);
success = true;
}
catch (Exit & e) {
Printer::log(M_ERROR, "We shouldn't have gotten an Exit exception here... exitting anyway");
auto trace = e.getTrace();
for (String & str : trace)
Printer::log(M_ERROR, "%s", str.to_charp());
}
catch (RessourceException & e) {
Printer::log(M_ERROR | M_ALERT, "The Thread got a ressource problem: %s", e.getMsg());
const char * details = e.getDetails();
if (details)
Printer::log(M_ERROR, " %s", details);
auto trace = e.getTrace();
for (String & str : trace)
Printer::log(M_DEBUG, "%s", str.to_charp());
}
catch (GeneralException & e) {
Printer::log(M_ERROR | M_ALERT, "The Thread caused an exception: %s", e.getMsg());
const char * details = e.getDetails();
if (details)
Printer::log(M_ERROR, " %s", details);
auto trace = e.getTrace();
for (String & str : trace)
Printer::log(M_DEBUG, "%s", str.to_charp());
}
catch (...) {
Printer::log(M_ERROR | M_ALERT, "The Thread caused an unknown exception");
}
if (!success)
TaskMan::stop(-1);
return r;
}
Balau::Thread::~Thread() {
join();
}
void * Balau::Thread::join() {
void * r = NULL;
if (!m_joined.exchange(true)) {
threadExit();
pthread_join(m_thread, &r);
}
return r;
}
void Balau::Thread::threadStart() {
pthread_attr_t attr;
int r;
r = pthread_attr_init(&attr);
RAssert(r == 0, "Couldn't initialize pthread attribute; r = %i", r);
r = pthread_create(&m_thread, &attr, Balau::ThreadHelper::threadProc, this);
RAssert(r == 0, "Couldn't create pthread; r = %i", r);
r = pthread_attr_destroy(&attr);
RAssert(r == 0, "Couldn't destroy pthread attribute; r = %i", r);
}
|