Skip to content

Commit 58645ac

Browse files
[C] Fix thread handling on Windows (#864)
- A function with the wrong signature was being passed to CreateThread - The thread handle was never closed - Failure to start a thread was not detected
1 parent 9513544 commit 58645ac

File tree

3 files changed

+60
-24
lines changed

3 files changed

+60
-24
lines changed

aeron-driver/src/main/c/aeron_agent.c

-4
Original file line numberDiff line numberDiff line change
@@ -418,11 +418,7 @@ static void *agent_main(void *arg)
418418
{
419419
aeron_agent_runner_t *runner = (aeron_agent_runner_t *)arg;
420420

421-
#if defined(Darwin)
422421
aeron_thread_set_name(runner->role_name);
423-
#else
424-
aeron_thread_set_name(aeron_thread_self(), runner->role_name);
425-
#endif
426422

427423
if (NULL != runner->on_start)
428424
{

aeron-driver/src/main/c/concurrent/aeron_thread.c

+51-12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
* limitations under the License.
1515
*/
1616

17+
#if defined(__linux__)
18+
#define _BSD_SOURCE
19+
#define _GNU_SOURCE
20+
#endif
21+
1722
#include "concurrent/aeron_thread.h"
1823

1924
void aeron_nano_sleep(uint64_t nanoseconds)
@@ -42,6 +47,16 @@ void aeron_nano_sleep(uint64_t nanoseconds)
4247
}
4348

4449
#if defined(AERON_COMPILER_GCC)
50+
51+
void aeron_thread_set_name(const char* role_name)
52+
{
53+
#if defined(Darwin)
54+
pthread_setname_np(role_name);
55+
#else
56+
pthread_setname_np(pthread_self(), role_name);
57+
#endif
58+
}
59+
4560
#elif defined(AERON_COMPILER_MSVC) && defined(AERON_CPU_X64)
4661

4762
static BOOL aeron_thread_once_callback(PINIT_ONCE init_once, void (*callback)(void), void** context)
@@ -75,38 +90,62 @@ int aeron_thread_attr_init(pthread_attr_t* attr)
7590
return 0;
7691
}
7792

93+
static DWORD WINAPI aeron_thread_proc(LPVOID parameter)
94+
{
95+
aeron_thread_t* thread = (aeron_thread_t*)parameter;
96+
thread->result = thread->callback(thread->arg0);
97+
return 0;
98+
}
99+
78100
int aeron_thread_create(aeron_thread_t* thread, void* attr, void*(*callback)(void*), void* arg0)
79101
{
102+
thread->callback = callback;
103+
thread->arg0 = arg0;
104+
80105
DWORD id;
81-
*thread = CreateThread(
106+
thread->handle = CreateThread(
82107
NULL, // default security attributes
83108
0, // use default stack size
84-
callback, // thread function name
85-
arg0, // argument to thread function
109+
aeron_thread_proc, // thread function name
110+
thread, // argument to thread function
86111
0, // use default creation flags
87112
&id); // returns the thread identifier
88113

89-
return 0;
114+
return thread->handle ? 0 : -1;
90115
}
91116

92-
void aeron_thread_set_name(aeron_thread_t self, const char* role_name)
117+
void aeron_thread_set_name(const char* role_name)
93118
{
94119
size_t wn = mbstowcs(NULL, role_name, 0);
95120
wchar_t * buf = malloc(sizeof(wchar_t) * (wn + 1)); // value-initialize to 0 (see below)
121+
if (!buf)
122+
{
123+
return;
124+
}
125+
96126
mbstowcs(buf, role_name, wn + 1);
97-
SetThreadDescription(self, buf);
127+
SetThreadDescription(GetCurrentThread(), buf);
98128

99129
free(buf);
100130
}
101131

102-
aeron_thread_t aeron_thread_self()
132+
int aeron_thread_join(aeron_thread_t thread, void **value_ptr)
103133
{
104-
return GetCurrentThread();
105-
}
134+
if (thread.handle)
135+
{
136+
WaitForSingleObject(thread.handle, INFINITE);
137+
CloseHandle(thread.handle);
138+
}
139+
else
140+
{
141+
return EINVAL;
142+
}
143+
144+
if (value_ptr)
145+
{
146+
*value_ptr = thread.result;
147+
}
106148

107-
DWORD aeron_thread_join(aeron_thread_t thread, void **value_ptr)
108-
{
109-
WaitForSingleObject(thread, INFINITE);
110149
return 0;
111150
}
112151

aeron-driver/src/main/c/concurrent/aeron_thread.h

+9-8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <stdint.h>
2323

24+
void aeron_thread_set_name(const char* role_name);
2425

2526
#if defined(AERON_COMPILER_GCC)
2627

@@ -36,8 +37,6 @@
3637
#define aeron_thread_once pthread_once
3738
#define aeron_thread_attr_init pthread_attr_init
3839
#define aeron_thread_create pthread_create
39-
#define aeron_thread_set_name pthread_setname_np
40-
#define aeron_thread_self pthread_self
4140
#define aeron_thread_join pthread_join
4241
#define aeron_thread_key_create pthread_key_create
4342
#define aeron_thread_key_delete pthread_key_delete
@@ -52,7 +51,13 @@
5251

5352
#define AERON_MUTEX HANDLE
5453

55-
typedef HANDLE aeron_thread_t;
54+
typedef struct
55+
{
56+
HANDLE handle;
57+
void* (*callback)(void*);
58+
void* arg0;
59+
void* result;
60+
} aeron_thread_t;
5661

5762
typedef INIT_ONCE AERON_INIT_ONCE;
5863

@@ -73,11 +78,7 @@
7378

7479
int aeron_thread_create(aeron_thread_t* thread, void* attr, void*(*callback)(void*), void* arg0);
7580

76-
void aeron_thread_set_name(aeron_thread_t self, const char* role_name);
77-
78-
aeron_thread_t aeron_thread_self();
79-
80-
DWORD aeron_thread_join(aeron_thread_t thread, void **value_ptr);
81+
int aeron_thread_join(aeron_thread_t thread, void **value_ptr);
8182

8283
int aeron_thread_key_create(pthread_key_t *key, void(*destr_function) (void *));
8384

0 commit comments

Comments
 (0)