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 "Thread.h"
22
23namespace love
24{
25namespace thread
26{
27namespace sdl
28{
29Thread::Thread(Threadable *t)
30 : t(t)
31 , running(false)
32 , thread(nullptr)
33{
34}
35
36Thread::~Thread()
37{
38 // Clean up handle
39 if (thread)
40 SDL_DetachThread(thread);
41}
42
43bool Thread::start()
44{
45#if defined(LOVE_LINUX)
46 // Temporarly block signals, as the thread inherits this mask
47 love::thread::ScopedDisableSignals disableSignals;
48#endif
49
50 Lock l(mutex);
51
52 if (running)
53 return false;
54
55 if (thread) // Clean old handle up
56 SDL_WaitThread(thread, nullptr);
57
58 // Keep the threadable around until the thread is done with it.
59 // This is done before thread_runner executes because there can be a delay
60 // between CreateThread and the start of the thread code's execution.
61 t->retain();
62
63 thread = SDL_CreateThread(thread_runner, t->getThreadName(), this);
64 running = (thread != nullptr);
65
66 if (!running)
67 t->release(); // thread_runner is never called in this situation.
68
69 return running;
70}
71
72void Thread::wait()
73{
74 {
75 Lock l(mutex);
76 if (!thread)
77 return;
78 }
79 SDL_WaitThread(thread, nullptr);
80 Lock l(mutex);
81 running = false;
82 thread = nullptr;
83}
84
85bool Thread::isRunning()
86{
87 Lock l(mutex);
88 return running;
89}
90
91int Thread::thread_runner(void *data)
92{
93 Thread *self = (Thread *) data; // some compilers don't like 'this'
94
95 self->t->threadFunction();
96
97 {
98 Lock l(self->mutex);
99 self->running = false;
100 }
101
102 // This was retained in start().
103 self->t->release();
104 return 0;
105}
106} // sdl
107} // thread
108} // love
109