mirror of
https://github.com/curl/curl.git
synced 2025-09-20 19:12:40 +03:00
windows: replace _beginthreadex()
with CreateThread()
Replace `_beginthreadex()` C runtime calls with native win32 API `CreateThread()`. The latter was already used in `src/tool_doswin.c` and in UWP and Windows CE builds before this patch. After this patch all Windows flavors use it. To drop PP logic and simplify code. While working on this it turned out that `src/tool_doswin.c` calls `TerminateThread()`, which isn't recommended by the documentation, except for "the most extreme cases". This patch makes no attempt to change that code. Ref:9a2663322c
#17572 Ref: https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminatethread Also: - use `WaitForSingleObjectEx()` on all desktop Windows. Ref:4be80d5109
Ref: https://sourceforge.net/p/curl/feature-requests/82/ Ref: https://learn.microsoft.com/windows/win32/api/synchapi/nf-synchapi-waitforsingleobjectex - tests: drop redundant casts. - lib3207: fix to not rely on thread macros when building without thread support. Assisted-by: Jay Satiro Assisted-by: Marcel Raad Assisted-by: Michał Petryka Follow-up to38029101e2
#11625 Closes #18451
This commit is contained in:
parent
8d004781a5
commit
1c49f2f26d
|
@ -26,12 +26,8 @@
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#ifdef USE_THREADS_POSIX
|
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||||
# ifdef HAVE_PTHREAD_H
|
#include <pthread.h>
|
||||||
# include <pthread.h>
|
|
||||||
# endif
|
|
||||||
#elif defined(USE_THREADS_WIN32)
|
|
||||||
# include <process.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "curl_threads.h"
|
#include "curl_threads.h"
|
||||||
|
@ -105,20 +101,8 @@ int Curl_thread_join(curl_thread_t *hnd)
|
||||||
curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T
|
curl_thread_t Curl_thread_create(CURL_THREAD_RETURN_T
|
||||||
(CURL_STDCALL *func) (void *), void *arg)
|
(CURL_STDCALL *func) (void *), void *arg)
|
||||||
{
|
{
|
||||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
curl_thread_t t = CreateThread(NULL, 0, func, arg, 0, NULL);
|
||||||
typedef HANDLE curl_win_thread_handle_t;
|
if(!t) {
|
||||||
#else
|
|
||||||
typedef uintptr_t curl_win_thread_handle_t;
|
|
||||||
#endif
|
|
||||||
curl_thread_t t;
|
|
||||||
curl_win_thread_handle_t thread_handle;
|
|
||||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
|
||||||
thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL);
|
|
||||||
#else
|
|
||||||
thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
|
|
||||||
#endif
|
|
||||||
t = (curl_thread_t)thread_handle;
|
|
||||||
if((t == 0) || (t == LongToHandle(-1L))) {
|
|
||||||
#ifdef UNDER_CE
|
#ifdef UNDER_CE
|
||||||
DWORD gle = GetLastError();
|
DWORD gle = GetLastError();
|
||||||
/* !checksrc! disable ERRNOVAR 1 */
|
/* !checksrc! disable ERRNOVAR 1 */
|
||||||
|
@ -142,7 +126,7 @@ void Curl_thread_destroy(curl_thread_t *hnd)
|
||||||
|
|
||||||
int Curl_thread_join(curl_thread_t *hnd)
|
int Curl_thread_join(curl_thread_t *hnd)
|
||||||
{
|
{
|
||||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < _WIN32_WINNT_VISTA)
|
#ifdef UNDER_CE
|
||||||
int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
|
int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
|
||||||
#else
|
#else
|
||||||
int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
|
int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#ifdef USE_THREADS_POSIX
|
#ifdef USE_THREADS_POSIX
|
||||||
|
# define CURL_THREAD_RETURN_T unsigned int
|
||||||
# define CURL_STDCALL
|
# define CURL_STDCALL
|
||||||
# define curl_mutex_t pthread_mutex_t
|
# define curl_mutex_t pthread_mutex_t
|
||||||
# define curl_thread_t pthread_t *
|
# define curl_thread_t pthread_t *
|
||||||
|
@ -35,7 +36,8 @@
|
||||||
# define Curl_mutex_release(m) pthread_mutex_unlock(m)
|
# define Curl_mutex_release(m) pthread_mutex_unlock(m)
|
||||||
# define Curl_mutex_destroy(m) pthread_mutex_destroy(m)
|
# define Curl_mutex_destroy(m) pthread_mutex_destroy(m)
|
||||||
#elif defined(USE_THREADS_WIN32)
|
#elif defined(USE_THREADS_WIN32)
|
||||||
# define CURL_STDCALL __stdcall
|
# define CURL_THREAD_RETURN_T DWORD
|
||||||
|
# define CURL_STDCALL WINAPI
|
||||||
# define curl_mutex_t CRITICAL_SECTION
|
# define curl_mutex_t CRITICAL_SECTION
|
||||||
# define curl_thread_t HANDLE
|
# define curl_thread_t HANDLE
|
||||||
# define curl_thread_t_null (HANDLE)0
|
# define curl_thread_t_null (HANDLE)0
|
||||||
|
@ -47,14 +49,6 @@
|
||||||
# define Curl_mutex_acquire(m) EnterCriticalSection(m)
|
# define Curl_mutex_acquire(m) EnterCriticalSection(m)
|
||||||
# define Curl_mutex_release(m) LeaveCriticalSection(m)
|
# define Curl_mutex_release(m) LeaveCriticalSection(m)
|
||||||
# define Curl_mutex_destroy(m) DeleteCriticalSection(m)
|
# define Curl_mutex_destroy(m) DeleteCriticalSection(m)
|
||||||
#else
|
|
||||||
# define CURL_STDCALL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
|
||||||
#define CURL_THREAD_RETURN_T DWORD
|
|
||||||
#else
|
|
||||||
#define CURL_THREAD_RETURN_T unsigned int
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||||
|
|
|
@ -26,12 +26,7 @@
|
||||||
#define NUM_THREADS 100
|
#define NUM_THREADS 100
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
static DWORD WINAPI t3026_run_thread(void *ptr)
|
||||||
static DWORD WINAPI t3026_run_thread(LPVOID ptr)
|
|
||||||
#else
|
|
||||||
#include <process.h>
|
|
||||||
static unsigned int WINAPI t3026_run_thread(void *ptr)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
CURLcode *result = ptr;
|
CURLcode *result = ptr;
|
||||||
|
|
||||||
|
@ -44,13 +39,8 @@ static unsigned int WINAPI t3026_run_thread(void *ptr)
|
||||||
|
|
||||||
static CURLcode test_lib3026(const char *URL)
|
static CURLcode test_lib3026(const char *URL)
|
||||||
{
|
{
|
||||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
|
||||||
typedef HANDLE curl_win_thread_handle_t;
|
|
||||||
#else
|
|
||||||
typedef uintptr_t curl_win_thread_handle_t;
|
|
||||||
#endif
|
|
||||||
CURLcode results[NUM_THREADS];
|
CURLcode results[NUM_THREADS];
|
||||||
curl_win_thread_handle_t thread_handles[NUM_THREADS];
|
HANDLE thread_handles[NUM_THREADS];
|
||||||
unsigned tid_count = NUM_THREADS, i;
|
unsigned tid_count = NUM_THREADS, i;
|
||||||
CURLcode test_failure = CURLE_OK;
|
CURLcode test_failure = CURLE_OK;
|
||||||
curl_version_info_data *ver;
|
curl_version_info_data *ver;
|
||||||
|
@ -65,13 +55,9 @@ static CURLcode test_lib3026(const char *URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < tid_count; i++) {
|
for(i = 0; i < tid_count; i++) {
|
||||||
curl_win_thread_handle_t th;
|
HANDLE th;
|
||||||
results[i] = CURL_LAST; /* initialize with invalid value */
|
results[i] = CURL_LAST; /* initialize with invalid value */
|
||||||
#if defined(CURL_WINDOWS_UWP) || defined(UNDER_CE)
|
|
||||||
th = CreateThread(NULL, 0, t3026_run_thread, &results[i], 0, NULL);
|
th = CreateThread(NULL, 0, t3026_run_thread, &results[i], 0, NULL);
|
||||||
#else
|
|
||||||
th = _beginthreadex(NULL, 0, t3026_run_thread, &results[i], 0, NULL);
|
|
||||||
#endif
|
|
||||||
if(!th) {
|
if(!th) {
|
||||||
curl_mfprintf(stderr, "%s:%d Couldn't create thread, errno %lu\n",
|
curl_mfprintf(stderr, "%s:%d Couldn't create thread, errno %lu\n",
|
||||||
__FILE__, __LINE__, GetLastError());
|
__FILE__, __LINE__, GetLastError());
|
||||||
|
@ -84,8 +70,8 @@ static CURLcode test_lib3026(const char *URL)
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
for(i = 0; i < tid_count; i++) {
|
for(i = 0; i < tid_count; i++) {
|
||||||
WaitForSingleObject((HANDLE)thread_handles[i], INFINITE);
|
WaitForSingleObject(thread_handles[i], INFINITE);
|
||||||
CloseHandle((HANDLE)thread_handles[i]);
|
CloseHandle(thread_handles[i]);
|
||||||
if(results[i] != CURLE_OK) {
|
if(results[i] != CURLE_OK) {
|
||||||
curl_mfprintf(stderr, "%s:%d thread[%u]: curl_global_init() failed,"
|
curl_mfprintf(stderr, "%s:%d thread[%u]: curl_global_init() failed,"
|
||||||
"with code %d (%s)\n", __FILE__, __LINE__,
|
"with code %d (%s)\n", __FILE__, __LINE__,
|
||||||
|
|
|
@ -68,7 +68,11 @@ static size_t write_memory_callback(char *contents, size_t size,
|
||||||
return realsize;
|
return realsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||||
static CURL_THREAD_RETURN_T CURL_STDCALL test_thread(void *ptr)
|
static CURL_THREAD_RETURN_T CURL_STDCALL test_thread(void *ptr)
|
||||||
|
#else
|
||||||
|
static unsigned int test_thread(void *ptr)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct Ctx *ctx = (struct Ctx *)ptr;
|
struct Ctx *ctx = (struct Ctx *)ptr;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
|
|
|
@ -412,8 +412,7 @@ struct select_ws_wait_data {
|
||||||
HANDLE signal; /* internal event to signal handle trigger */
|
HANDLE signal; /* internal event to signal handle trigger */
|
||||||
HANDLE abort; /* internal event to abort waiting threads */
|
HANDLE abort; /* internal event to abort waiting threads */
|
||||||
};
|
};
|
||||||
#include <process.h>
|
static DWORD WINAPI select_ws_wait_thread(void *lpParameter)
|
||||||
static unsigned int WINAPI select_ws_wait_thread(void *lpParameter)
|
|
||||||
{
|
{
|
||||||
struct select_ws_wait_data *data;
|
struct select_ws_wait_data *data;
|
||||||
HANDLE signal, handle, handles[2];
|
HANDLE signal, handle, handles[2];
|
||||||
|
@ -557,25 +556,25 @@ static unsigned int WINAPI select_ws_wait_thread(void *lpParameter)
|
||||||
|
|
||||||
static HANDLE select_ws_wait(HANDLE handle, HANDLE signal, HANDLE abort)
|
static HANDLE select_ws_wait(HANDLE handle, HANDLE signal, HANDLE abort)
|
||||||
{
|
{
|
||||||
typedef uintptr_t curl_win_thread_handle_t;
|
|
||||||
struct select_ws_wait_data *data;
|
struct select_ws_wait_data *data;
|
||||||
curl_win_thread_handle_t thread;
|
|
||||||
|
|
||||||
/* allocate internal waiting data structure */
|
/* allocate internal waiting data structure */
|
||||||
data = malloc(sizeof(struct select_ws_wait_data));
|
data = malloc(sizeof(struct select_ws_wait_data));
|
||||||
if(data) {
|
if(data) {
|
||||||
|
HANDLE thread;
|
||||||
|
|
||||||
data->handle = handle;
|
data->handle = handle;
|
||||||
data->signal = signal;
|
data->signal = signal;
|
||||||
data->abort = abort;
|
data->abort = abort;
|
||||||
|
|
||||||
/* launch waiting thread */
|
/* launch waiting thread */
|
||||||
thread = _beginthreadex(NULL, 0, &select_ws_wait_thread, data, 0, NULL);
|
thread = CreateThread(NULL, 0, &select_ws_wait_thread, data, 0, NULL);
|
||||||
|
|
||||||
/* free data if thread failed to launch */
|
/* free data if thread failed to launch */
|
||||||
if(!thread) {
|
if(!thread) {
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
return (HANDLE)thread;
|
return thread;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,7 +350,7 @@ static SIGHANDLER_T old_sigbreak_handler = SIG_ERR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
|
#if defined(_WIN32) && !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
|
||||||
static unsigned int thread_main_id = 0;
|
static DWORD thread_main_id = 0;
|
||||||
static HANDLE thread_main_window = NULL;
|
static HANDLE thread_main_window = NULL;
|
||||||
static HWND hidden_main_window = NULL;
|
static HWND hidden_main_window = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -487,8 +487,7 @@ static LRESULT CALLBACK main_window_proc(HWND hwnd, UINT uMsg,
|
||||||
}
|
}
|
||||||
/* Window message queue loop for hidden main window, details see above.
|
/* Window message queue loop for hidden main window, details see above.
|
||||||
*/
|
*/
|
||||||
#include <process.h>
|
static DWORD WINAPI main_window_loop(void *lpParameter)
|
||||||
static unsigned int WINAPI main_window_loop(void *lpParameter)
|
|
||||||
{
|
{
|
||||||
WNDCLASS wc;
|
WNDCLASS wc;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -509,7 +508,7 @@ static unsigned int WINAPI main_window_loop(void *lpParameter)
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
(HWND)NULL, (HMENU)NULL,
|
(HWND)NULL, (HMENU)NULL,
|
||||||
wc.hInstance, (LPVOID)NULL);
|
wc.hInstance, NULL);
|
||||||
if(!hidden_main_window) {
|
if(!hidden_main_window) {
|
||||||
win32_perror("CreateWindowEx failed");
|
win32_perror("CreateWindowEx failed");
|
||||||
return (DWORD)-1;
|
return (DWORD)-1;
|
||||||
|
@ -623,15 +622,10 @@ void install_signal_handlers(bool keep_sigalrm)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
|
#if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
|
||||||
{
|
thread_main_window = CreateThread(NULL, 0, &main_window_loop,
|
||||||
typedef uintptr_t curl_win_thread_handle_t;
|
GetModuleHandle(NULL), 0, &thread_main_id);
|
||||||
curl_win_thread_handle_t thread;
|
if(!thread_main_window || !thread_main_id)
|
||||||
thread = _beginthreadex(NULL, 0, &main_window_loop,
|
logmsg("cannot start main window loop");
|
||||||
(void *)GetModuleHandle(NULL), 0, &thread_main_id);
|
|
||||||
thread_main_window = (HANDLE)thread;
|
|
||||||
if(!thread_main_window || !thread_main_id)
|
|
||||||
logmsg("cannot start main window loop");
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user