YAZ  5.34.0
thread_create.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14 
15 #include <assert.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <stddef.h>
20 #include <yaz/xmalloc.h>
21 #include <yaz/log.h>
22 #include <yaz/thread_create.h>
23 
24 #if YAZ_POSIX_THREADS
25 #include <pthread.h>
26 #endif
27 #ifdef WIN32
28 #include <windows.h>
29 #include <process.h>
30 #endif
31 
32 struct yaz_thread {
33 #if YAZ_POSIX_THREADS
34  pthread_t id;
35 #else
36 #ifdef WIN32
37  HANDLE handle;
38  void *(*routine)(void *p);
39 #endif
40  void *data;
41 #endif
42 };
43 
44 #ifdef WIN32
45 unsigned int __stdcall win32_routine(void *p)
46 {
47  yaz_thread_t t = (yaz_thread_t) p;
48  void *userdata = t->data;
49  t->data = t->routine(userdata);
50  _endthreadex(0);
51  return 0;
52 }
53 #endif
54 
55 yaz_thread_t yaz_thread_create(void *(*start_routine)(void *p), void *arg)
56 {
57  yaz_thread_t t = xmalloc(sizeof(*t));
58 #if YAZ_POSIX_THREADS
59  int r = pthread_create(&t->id, 0, start_routine, arg);
60  if (r)
61  {
62  xfree(t);
63  t = 0;
64  }
65 #else
66 #ifdef WIN32
67  /* we create a wrapper on windows and pass yaz_thread struct to that */
68  unsigned threadID;
69  uintptr_t ex_ret;
70  t->data = arg; /* use data for both input and output */
71  t->routine = start_routine;
72  ex_ret = _beginthreadex(NULL, 0, win32_routine, t, 0, &threadID);
73  if (ex_ret == -1L)
74  {
75  xfree(t);
76  t = 0;
77  }
78  t->handle = (HANDLE) ex_ret;
79 #else
80  t->data = start_routine(arg);
81 #endif
82 #endif
83  return t;
84 }
85 
86 void yaz_thread_join(yaz_thread_t *tp, void **value_ptr)
87 {
88  if (*tp)
89  {
90 #ifdef YAZ_POSIX_THREADS
91  pthread_join((*tp)->id, value_ptr);
92 #else
93 #ifdef WIN32
94  WaitForSingleObject((*tp)->handle, INFINITE);
95  CloseHandle((*tp)->handle);
96 #endif
97  if (value_ptr)
98  *value_ptr = (*tp)->data;
99 #endif
100  xfree(*tp);
101  *tp = 0;
102  }
103 }
104 
106 {
107  if (*tp)
108  {
109 #ifdef YAZ_POSIX_THREADS
110  pthread_detach((*tp)->id);
111 #else
112 #ifdef WIN32
113  CloseHandle((*tp)->handle);
114 #endif
115 #endif
116  xfree(*tp);
117  *tp = 0;
118  }
119 }
120 
121 /*
122  * Local variables:
123  * c-basic-offset: 4
124  * c-file-style: "Stroustrup"
125  * indent-tabs-mode: nil
126  * End:
127  * vim: shiftwidth=4 tabstop=8 expandtab
128  */
129 
Header for errno utilities.
Logging utility.
void * data
Definition: thread_create.c:40
void yaz_thread_detach(yaz_thread_t *tp)
detach thread
yaz_thread_t yaz_thread_create(void *(*start_routine)(void *p), void *arg)
create thread
Definition: thread_create.c:55
void yaz_thread_join(yaz_thread_t *tp, void **value_ptr)
join thread
Definition: thread_create.c:86
Implements thread creation wrappers.
struct yaz_thread * yaz_thread_t
Thread Identifier opaque pointer.
Definition: thread_create.h:42
Header for memory handling functions.
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49