2
* WinPR: Windows Portable Runtime
3
* Process Thread Functions
5
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7
* Licensed under the Apache License, Version 2.0 (the "License");
8
* you may not use this file except in compliance with the License.
9
* You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
24
#include <winpr/handle.h>
26
#include <winpr/thread.h>
29
* api-ms-win-core-processthreads-l1-1-1.dll
32
* CreateRemoteThreadEx
34
* DeleteProcThreadAttributeList
36
* FlushInstructionCache
37
* FlushProcessWriteBuffers
40
* GetCurrentThreadStackLimits
46
* GetThreadIdealProcessorEx
48
* GetThreadPriorityBoost
50
* InitializeProcThreadAttributeList
53
* QueryProcessAffinityUpdateMode
59
* SetThreadPriorityBoost
60
* SetThreadStackGuarantee
65
* UpdateProcThreadAttribute
70
#include <winpr/crt.h>
74
#include "../handle/handle.h"
77
* TODO: implement thread suspend/resume using pthreads
78
* http://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition
81
void winpr_StartThread(WINPR_THREAD* thread)
85
pthread_attr_init(&attr);
86
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
88
if (thread->dwStackSize > 0)
89
pthread_attr_setstacksize(&attr, (size_t) thread->dwStackSize);
91
thread->started = TRUE;
92
pthread_create(&thread->thread, &attr, (pthread_start_routine) thread->lpStartAddress, thread->lpParameter);
94
pthread_attr_destroy(&attr);
97
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
98
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
101
WINPR_THREAD* thread;
103
thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD));
104
ZeroMemory(thread, sizeof(WINPR_THREAD));
106
thread->started = FALSE;
107
thread->dwStackSize = dwStackSize;
108
thread->lpParameter = lpParameter;
109
thread->lpStartAddress = lpStartAddress;
110
thread->lpThreadAttributes = lpThreadAttributes;
112
pthread_mutex_init(&thread->mutex, 0);
114
WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD);
115
handle = (HANDLE) thread;
117
if (!(dwCreationFlags & CREATE_SUSPENDED))
118
winpr_StartThread(thread);
123
HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
124
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
129
VOID ExitThread(DWORD dwExitCode)
131
pthread_exit((void*) (size_t) dwExitCode);
134
BOOL GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode)
138
WINPR_THREAD* thread;
140
if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
143
thread = (WINPR_THREAD*) Object;
145
*lpExitCode = thread->dwExitCode;
150
HANDLE _GetCurrentThread(VOID)
155
DWORD GetCurrentThreadId(VOID)
158
tid = pthread_self();
162
DWORD ResumeThread(HANDLE hThread)
166
WINPR_THREAD* thread;
168
if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
171
thread = (WINPR_THREAD*) Object;
173
pthread_mutex_lock(&thread->mutex);
175
if (!thread->started)
176
winpr_StartThread(thread);
178
pthread_mutex_unlock(&thread->mutex);
183
DWORD SuspendThread(HANDLE hThread)
188
BOOL SwitchToThread(VOID)
193
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode)
197
WINPR_THREAD* thread;
199
if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
202
thread = (WINPR_THREAD*) Object;
204
pthread_mutex_lock(&thread->mutex);
207
pthread_cancel(thread->thread);
210
pthread_mutex_unlock(&thread->mutex);