ObjFW  Check-in [e342aa8358]

Overview
Comment:Add a function wrapper for threads on Windows

This is necessary because CreateThread() expects the function to be
stdcall, while the one we get passed is cdecl.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e342aa83588372501bb18ec837ece99fc18a7a2ce095fae25aa043c6248d2bc2
User & Date: js on 2020-06-14 15:50:47
Other Links: manifest | tags
Context
2020-06-14
16:07
Check thread attributes before spawning the thread check-in: 164475afdb user: js tags: trunk
15:50
Add a function wrapper for threads on Windows check-in: e342aa8358 user: js tags: trunk
15:32
Fix releasing semaphore stored in free'd memory check-in: 903b3326e2 user: js tags: trunk
Changes

Modified src/platform/windows/thread.m from [6d8493f63f] to [ec067e732d].

19
20
21
22
23
24
25













26
27
28
29
30
31
32
33
34
35
36
37
38
39

40









41
42
43
44


45
46
47
48
49
50
51
52
53
54




55
56
57
58
59
60
61

#include <errno.h>

#import "thread.h"
#import "macros.h"

#include <windows.h>














bool
of_thread_attr_init(of_thread_attr_t *attr)
{
	attr->priority = 0;
	attr->stackSize = 0;

	return true;
}

bool
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
    id object, const of_thread_attr_t *attr)
{

	DWORD threadID;









	*thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
	    (LPTHREAD_START_ROUTINE)function, (void *)object, 0, &threadID);

	if (thread == NULL) {


		switch (GetLastError()) {
		case ERROR_NOT_ENOUGH_MEMORY:
			errno = ENOMEM;
			return false;
		case ERROR_ACCESS_DENIED:
			errno = EACCES;
			return false;
		default:
			OF_ENSURE(0);
		}




	}

	if (attr != NULL && attr->priority != 0) {
		DWORD priority;

		if (attr->priority < -1 || attr->priority > 1) {
			errno = EINVAL;







>
>
>
>
>
>
>
>
>
>
>
>
>














>

>
>
>
>
>
>
>
>
>

|


>
>


|
|

|
|



>
>
>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

#include <errno.h>

#import "thread.h"
#import "macros.h"

#include <windows.h>

struct thread_context {
	void (*function)(id);
	id object;
};

static WINAPI void
functionWrapper(struct thread_context *context)
{
	context->function(context->object);

	free(context);
}

bool
of_thread_attr_init(of_thread_attr_t *attr)
{
	attr->priority = 0;
	attr->stackSize = 0;

	return true;
}

bool
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
    id object, const of_thread_attr_t *attr)
{
	struct thread_context *context;
	DWORD threadID;

	if ((context = malloc(sizeof(*context))) == NULL) {
		errno = ENOMEM;
		return false;
	}

	context->function = function;
	context->object = object;

	*thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
	    (LPTHREAD_START_ROUTINE)functionWrapper, context, 0, &threadID);

	if (thread == NULL) {
		int errNo;

		switch (GetLastError()) {
		case ERROR_NOT_ENOUGH_MEMORY:
			errNo = ENOMEM;
			break;
		case ERROR_ACCESS_DENIED:
			errNo = EACCES;
			break;
		default:
			OF_ENSURE(0);
		}

		free(context);
		errno = errNo;
		return false;
	}

	if (attr != NULL && attr->priority != 0) {
		DWORD priority;

		if (attr->priority < -1 || attr->priority > 1) {
			errno = EINVAL;