SDL

Форк
0
/
SDL_systhread.cpp 
169 строк · 4.5 Кб
1
/*
2
  Simple DirectMedia Layer
3
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
4

5
  This software is provided 'as-is', without any express or implied
6
  warranty.  In no event will the authors be held liable for any damages
7
  arising from the use of this software.
8

9
  Permission is granted to anyone to use this software for any purpose,
10
  including commercial applications, and to alter it and redistribute it
11
  freely, subject to the following restrictions:
12

13
  1. The origin of this software must not be misrepresented; you must not
14
     claim that you wrote the original software. If you use this software
15
     in a product, an acknowledgment in the product documentation would be
16
     appreciated but is not required.
17
  2. Altered source versions must be plainly marked as such, and must not be
18
     misrepresented as being the original software.
19
  3. This notice may not be removed or altered from any source distribution.
20
*/
21
#include "SDL_internal.h"
22

23
// Thread management routines for SDL
24

25
extern "C" {
26
#include "../SDL_thread_c.h"
27
#include "../SDL_systhread.h"
28
}
29

30
#include <thread>
31
#include <system_error>
32

33
#ifdef SDL_PLATFORM_WINRT
34
#include <Windows.h>
35
#endif
36

37
static void RunThread(void *args)
38
{
39
    SDL_RunThread((SDL_Thread *)args);
40
}
41

42
extern "C"
43
bool SDL_SYS_CreateThread(SDL_Thread *thread,
44
                     SDL_FunctionPointer pfnBeginThread,
45
                     SDL_FunctionPointer pfnEndThread)
46
{
47
    try {
48
        // !!! FIXME: no way to set a thread stack size here.
49
        thread->handle = (void *)new std::thread(RunThread, thread);
50
        return true;
51
    } catch (std::system_error &ex) {
52
        return SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code().value(), ex.what());
53
    } catch (std::bad_alloc &) {
54
        return SDL_OutOfMemory();
55
    }
56
}
57

58
extern "C"
59
void SDL_SYS_SetupThread(const char *name)
60
{
61
    // Do nothing.
62
}
63

64
extern "C"
65
SDL_ThreadID SDL_GetCurrentThreadID(void)
66
{
67
    static_assert(sizeof(std::thread::id) <= sizeof(SDL_ThreadID), "std::thread::id must not be bigger than SDL_ThreadID");
68
    SDL_ThreadID thread_id{};
69
    const auto cpp_thread_id = std::this_thread::get_id();
70
    SDL_memcpy(&thread_id, &cpp_thread_id, sizeof(std::thread::id));
71
    return thread_id;
72
}
73

74
extern "C"
75
bool SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
76
{
77
#ifdef SDL_PLATFORM_WINRT
78
    int value;
79

80
    if (priority == SDL_THREAD_PRIORITY_LOW) {
81
        value = THREAD_PRIORITY_LOWEST;
82
    } else if (priority == SDL_THREAD_PRIORITY_HIGH) {
83
        value = THREAD_PRIORITY_HIGHEST;
84
    } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
85
        // FIXME: WinRT does not support TIME_CRITICAL! -flibit
86
        SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "TIME_CRITICAL unsupported, falling back to HIGHEST");
87
        value = THREAD_PRIORITY_HIGHEST;
88
    } else {
89
        value = THREAD_PRIORITY_NORMAL;
90
    }
91
    if (!SetThreadPriority(GetCurrentThread(), value)) {
92
        return WIN_SetError("SetThreadPriority()");
93
    }
94
    return true;
95
#else
96
    return SDL_Unsupported();
97
#endif
98
}
99

100
extern "C"
101
void SDL_SYS_WaitThread(SDL_Thread *thread)
102
{
103
    if (!thread) {
104
        return;
105
    }
106

107
    try {
108
        std::thread *cpp_thread = (std::thread *)thread->handle;
109
        if (cpp_thread) {
110
            if (cpp_thread->joinable()) {
111
                cpp_thread->join();
112
            }
113
            delete cpp_thread;
114
            thread->handle = nullptr;
115
        }
116
    } catch (std::system_error &) {
117
        // An error occurred when joining the thread.  SDL_WaitThread does not,
118
        // however, seem to provide a means to report errors to its callers
119
        // though!
120
    }
121
}
122

123
extern "C"
124
void SDL_SYS_DetachThread(SDL_Thread *thread)
125
{
126
    if (!thread) {
127
        return;
128
    }
129

130
    try {
131
        std::thread *cpp_thread = (std::thread *)thread->handle;
132
        if (cpp_thread) {
133
            if (cpp_thread->joinable()) {
134
                cpp_thread->detach();
135
            }
136
            delete cpp_thread;
137
            thread->handle = nullptr;
138
        }
139
    } catch (std::system_error &) {
140
        // An error occurred when detaching the thread.  SDL_DetachThread does not,
141
        // however, seem to provide a means to report errors to its callers
142
        // though!
143
    }
144
}
145

146
static thread_local SDL_TLSData *thread_local_storage;
147

148
extern "C"
149
void SDL_SYS_InitTLSData(void)
150
{
151
}
152

153
extern "C"
154
SDL_TLSData * SDL_SYS_GetTLSData(void)
155
{
156
    return thread_local_storage;
157
}
158

159
extern "C"
160
bool SDL_SYS_SetTLSData(SDL_TLSData *data)
161
{
162
    thread_local_storage = data;
163
    return true;
164
}
165

166
extern "C"
167
void SDL_SYS_QuitTLSData(void)
168
{
169
}
170

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.