simplify return handling, rearrange args
[rofl0r-thread_wrapper.git] / thread_test.c
blobd95c2abd7159e59d87185a93eb158fe22e4d1f95
1 /*
2 gcc -Wall -Wextra thread_test.c -g -lpthread
3 */
4 #include <pthread.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <stdlib.h>
10 #define KB(x) (x * 1024)
13 /* we want to call this func from a thread. */
14 int worker_func(int x, void* y, int z) {
15 return z;
18 typedef struct {
19 pthread_attr_t attr;
20 pthread_t thread;
21 int result;
22 int x;
23 void* y;
24 int z;
25 } worker_func_thread_data;
27 static void* worker_func_child_thread(void* data) {
28 worker_func_thread_data *child_thread_data = (worker_func_thread_data*)data;
29 child_thread_data->result = worker_func(child_thread_data->x, child_thread_data->y, child_thread_data->z);
30 return NULL;
33 /* returns NULL on success, otherwise error message string
34 * if an error happens, the pthread_attr_t member of ti gets
35 * automatically cleaned up. */
36 static const char* worker_func_thread_launcher(size_t stacksize, worker_func_thread_data** ti, int x, void* y, int z) {
37 const char* errmsg = NULL;
38 *ti = calloc(1, sizeof(worker_func_thread_data));
39 (*ti)->x = x;
40 (*ti)->y = y;
41 (*ti)->z = z;
43 if((errno = pthread_attr_init(&(*ti)->attr))) {
44 errmsg = "pthread_attr_init";
45 goto ret;
48 if((errno = pthread_attr_setstacksize(&(*ti)->attr, stacksize))) {
49 errmsg = "pthread_attr_setstacksize";
50 goto pt_err_attr;
52 if((errno = pthread_create(&(*ti)->thread, &(*ti)->attr, worker_func_child_thread, *ti))) {
53 errmsg = "pthread_create";
54 goto pt_err_attr;
57 ret:
58 return errmsg;
60 pt_err_attr:
61 pthread_attr_destroy(&(*ti)->attr);
62 goto ret;
65 static const char* worker_func_wait(int* result, worker_func_thread_data** ti) {
66 const char* errmsg = NULL;
68 if((errno = pthread_join((*ti)->thread, NULL))) {
69 errmsg = "pthread_join";
70 pthread_attr_destroy(&(*ti)->attr);
71 goto ret;
73 if((errno = pthread_attr_destroy(&(*ti)->attr))) {
74 errmsg = "pthread_attr_destroy";
76 *result = (*ti)->result;
77 ret:
78 free(*ti);
79 *ti = NULL;
80 return errmsg;
83 int main() {
84 worker_func_thread_data* child;
85 int result;
86 const char* errmsg;
87 if((errmsg = worker_func_thread_launcher(KB(128), &child, 0, NULL, 1))) goto pt_err;
88 if((errmsg = worker_func_wait(&result, &child))) goto pt_err;
90 printf("workerfunc returned %d\n", result);
92 return 0;
93 pt_err:
94 perror(errmsg);
95 return 1;