1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#include "threads.h"
22
23#if defined(LOVE_LINUX)
24#include <signal.h>
25#endif
26
27namespace love
28{
29namespace thread
30{
31
32Lock::Lock(Mutex *m)
33 : mutex(m)
34{
35 mutex->lock();
36}
37
38Lock::Lock(Mutex &m)
39 : mutex(&m)
40{
41 mutex->lock();
42}
43
44Lock::Lock(Lock &&other)
45{
46 mutex = other.mutex;
47 other.mutex = nullptr;
48}
49
50Lock::~Lock()
51{
52 if (mutex)
53 mutex->unlock();
54}
55
56EmptyLock::EmptyLock()
57 : mutex(nullptr)
58{
59}
60
61EmptyLock::~EmptyLock()
62{
63 if (mutex)
64 mutex->unlock();
65}
66
67void EmptyLock::setLock(Mutex *m)
68{
69 if (m)
70 m->lock();
71
72 if (mutex)
73 mutex->unlock();
74
75 mutex = m;
76}
77
78void EmptyLock::setLock(Mutex &m)
79{
80 m.lock();
81
82 if (mutex)
83 mutex->unlock();
84
85 mutex = &m;
86}
87
88love::Type Threadable::type("Threadable", &Object::type);
89
90Threadable::Threadable()
91{
92 owner = newThread(this);
93}
94
95Threadable::~Threadable()
96{
97 delete owner;
98}
99
100bool Threadable::start()
101{
102 return owner->start();
103}
104
105void Threadable::wait()
106{
107 owner->wait();
108}
109
110bool Threadable::isRunning() const
111{
112 return owner->isRunning();
113}
114
115const char *Threadable::getThreadName() const
116{
117 return threadName.empty() ? nullptr : threadName.c_str();
118}
119
120MutexRef::MutexRef()
121 : mutex(newMutex())
122{
123}
124
125MutexRef::~MutexRef()
126{
127 delete mutex;
128}
129
130MutexRef::operator Mutex*() const
131{
132 return mutex;
133}
134
135Mutex *MutexRef::operator->() const
136{
137 return mutex;
138}
139
140ConditionalRef::ConditionalRef()
141 : conditional(newConditional())
142{
143}
144
145ConditionalRef::~ConditionalRef()
146{
147 delete conditional;
148}
149
150ConditionalRef::operator Conditional*() const
151{
152 return conditional;
153}
154
155Conditional *ConditionalRef::operator->() const
156{
157 return conditional;
158}
159
160#if defined(LOVE_LINUX)
161static sigset_t oldset;
162
163void disableSignals()
164{
165 sigset_t newset;
166 sigfillset(&newset);
167 pthread_sigmask(SIG_SETMASK, &newset, &oldset);
168}
169
170void reenableSignals()
171{
172 pthread_sigmask(SIG_SETMASK, &oldset, nullptr);
173}
174#endif
175
176} // thread
177} // love
178