ObjFW  Check-in [77780c7596]

Overview
Comment:OFThread: Allow specifying a name before starting

This allows specifying a name before the thread gets started, so that
the name can be decided by whoever starts the thread, rather than just
by the thread itself once it's running.

This is especially useful as some operating systems do not support
changing the name of the thread once it's running.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 77780c7596412ee236d45f10d5b901145d09839d2dac738601d76ef5aac35b58
User & Date: js on 2019-09-01 15:29:31
Other Links: manifest | tags
Context
2019-09-01
16:53
Remove remaining uses of lrint() check-in: e702135e17 user: js tags: trunk
15:29
OFThread: Allow specifying a name before starting check-in: 77780c7596 user: js tags: trunk
15:20
Use u suffix on a few constants check-in: b7badc68a0 user: js tags: trunk
Changes

Modified src/OFThread.m from [fe6d085eae] to [67276b0c18].

411
412
413
414
415
416
417
418


419
420
421
422
423
424
425
		[_returnValue release];
	}

	[self retain];

	_running = OF_THREAD_RUNNING;

	if (!of_thread_new(&_thread, callMain, self, &_attr)) {


		[self release];
		@throw [OFThreadStartFailedException
		    exceptionWithThread: self
				  errNo: errno];
	}
}








|
>
>







411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
		[_returnValue release];
	}

	[self retain];

	_running = OF_THREAD_RUNNING;

	if (!of_thread_new(&_thread,
	    [_name cStringWithEncoding: [OFLocale encoding]], callMain, self,
	    &_attr)) {
		[self release];
		@throw [OFThreadStartFailedException
		    exceptionWithThread: self
				  errNo: errno];
	}
}

Modified src/thread.h from [a4fe604036] to [683e2810eb].

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
extern of_thread_t of_thread_current(void);
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_thread_attr_init(of_thread_attr_t *attr);
extern bool of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr);
extern void of_thread_set_name(const char *name);
extern bool of_thread_join(of_thread_t thread);
extern bool of_thread_detach(of_thread_t thread);
#ifdef __cplusplus
}
#endif







|
|






62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
extern of_thread_t of_thread_current(void);
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_thread_attr_init(of_thread_attr_t *attr);
extern bool of_thread_new(of_thread_t *thread, const char *name,
    void (*function)(id), id object, const of_thread_attr_t *attr);
extern void of_thread_set_name(const char *name);
extern bool of_thread_join(of_thread_t thread);
extern bool of_thread_detach(of_thread_t thread);
#ifdef __cplusplus
}
#endif

Modified src/thread_amiga.m from [ec9f55781b] to [64c90b6dca].

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	attr->priority = 0;
	attr->stackSize = 0;

	return true;
}

bool
of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr)
{
	OFMutableData *tags = nil;

	if ((*thread = calloc(1, sizeof(**thread))) == NULL) {
		errno = ENOMEM;
		return false;
	}







|
|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	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)
{
	OFMutableData *tags = nil;

	if ((*thread = calloc(1, sizeof(**thread))) == NULL) {
		errno = ENOMEM;
		return false;
	}
102
103
104
105
106
107
108


109
110
111
112
113
114
115
		ADD_TAG(NP_ExitData, (ULONG)*thread)
#ifdef OF_AMIGAOS4
		ADD_TAG(NP_Child, TRUE)
#endif
#ifdef OF_MORPHOS
		ADD_TAG(NP_CodeType, CODETYPE_PPC);
#endif



		ADD_TAG(NP_Input, ((struct Process *)FindTask(NULL))->pr_CIS)
		ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS)
		ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES)
		ADD_TAG(NP_CloseInput, FALSE)
		ADD_TAG(NP_CloseOutput, FALSE)
		ADD_TAG(NP_CloseError, FALSE)







>
>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
		ADD_TAG(NP_ExitData, (ULONG)*thread)
#ifdef OF_AMIGAOS4
		ADD_TAG(NP_Child, TRUE)
#endif
#ifdef OF_MORPHOS
		ADD_TAG(NP_CodeType, CODETYPE_PPC);
#endif
		if (name != NULL)
			ADD_TAG(NP_Name, (ULONG)name);

		ADD_TAG(NP_Input, ((struct Process *)FindTask(NULL))->pr_CIS)
		ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS)
		ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES)
		ADD_TAG(NP_CloseInput, FALSE)
		ADD_TAG(NP_CloseOutput, FALSE)
		ADD_TAG(NP_CloseError, FALSE)

Modified src/thread_pthread.m from [e8b813b448] to [16b08dae34].

28
29
30
31
32
33
34

35
36
37
38
39
40
41
#import "macros.h"

static int minPrio = 0, maxPrio = 0, normalPrio = 0;

struct thread_ctx {
	void (*function)(id object);
	id object;

};

/*
 * This is done here to make sure this is done as early as possible in the main
 * thread.
 */
OF_CONSTRUCTOR()







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#import "macros.h"

static int minPrio = 0, maxPrio = 0, normalPrio = 0;

struct thread_ctx {
	void (*function)(id object);
	id object;
	const char *name;
};

/*
 * This is done here to make sure this is done as early as possible in the main
 * thread.
 */
OF_CONSTRUCTOR()
68
69
70
71
72
73
74



75
76
77
78
79
80
81
}

static void *
functionWrapper(void *data)
{
	struct thread_ctx *ctx = data;




	pthread_cleanup_push(free, data);

	ctx->function(ctx->object);

	pthread_cleanup_pop(1);
	return NULL;
}







>
>
>







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
}

static void *
functionWrapper(void *data)
{
	struct thread_ctx *ctx = data;

	if (ctx->name != NULL)
		of_thread_set_name(ctx->name);

	pthread_cleanup_push(free, data);

	ctx->function(ctx->object);

	pthread_cleanup_pop(1);
	return NULL;
}
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
		pthread_attr_destroy(&pattr);
	}

	return true;
}

bool
of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr)
{
	bool ret;
	pthread_attr_t pattr;

	if (pthread_attr_init(&pattr) != 0)
		return false;








|
|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
		pthread_attr_destroy(&pattr);
	}

	return true;
}

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

	if (pthread_attr_init(&pattr) != 0)
		return false;

148
149
150
151
152
153
154

155
156
157
158
159
160
161
		if ((ctx = malloc(sizeof(*ctx))) == NULL) {
			errno = ENOMEM;
			return false;
		}

		ctx->function = function;
		ctx->object = object;


		ret = (pthread_create(thread, &pattr,
		    functionWrapper, ctx) == 0);
	} @finally {
		pthread_attr_destroy(&pattr);
	}








>







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
		if ((ctx = malloc(sizeof(*ctx))) == NULL) {
			errno = ENOMEM;
			return false;
		}

		ctx->function = function;
		ctx->object = object;
		ctx->name = name;

		ret = (pthread_create(thread, &pattr,
		    functionWrapper, ctx) == 0);
	} @finally {
		pthread_attr_destroy(&pattr);
	}

Modified src/thread_winapi.m from [7f82a998d7] to [1837a02e3e].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
	attr->priority = 0;
	attr->stackSize = 0;

	return true;
}

bool
of_thread_new(of_thread_t *thread, void (*function)(id), id object,
    const of_thread_attr_t *attr)
{
	*thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
	    (LPTHREAD_START_ROUTINE)function, (void *)object, 0, NULL);

	if (thread == NULL) {
		switch (GetLastError()) {
		case ERROR_NOT_ENOUGH_MEMORY:







|
|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
	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)
{
	*thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
	    (LPTHREAD_START_ROUTINE)function, (void *)object, 0, NULL);

	if (thread == NULL) {
		switch (GetLastError()) {
		case ERROR_NOT_ENOUGH_MEMORY: