Freeciv-3.1: /fast/freeciv/nightly/S3_1/utility/fcthread.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
fcthread.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "log.h"
20#include "mem.h"
21#include "support.h"
22
23#include "fcthread.h"
24
25#ifdef FREECIV_C11_THR
26
27struct fc_thread_wrap_data {
28 void *arg;
29 void (*func)(void *arg);
30};
31
32/*******************************************************************/
36static int fc_thread_wrapper(void *arg)
37{
38 struct fc_thread_wrap_data *data = (struct fc_thread_wrap_data *) arg;
39
40 data->func(data->arg);
41
42 free(data);
43
44 return EXIT_SUCCESS;
45}
46
47/*******************************************************************/
50int fc_thread_start(fc_thread *thread, void (*function) (void *arg),
51 void *arg)
52{
53 int ret;
54
55 /* Freed by child thread once it's finished with data */
56 struct fc_thread_wrap_data *data = fc_malloc(sizeof(*data));
57
58 data->arg = arg;
59 data->func = function;
60
61 ret = thrd_create(thread, &fc_thread_wrapper, data);
62
63 return ret != thrd_success;
64}
65
66/*******************************************************************/
69void fc_thread_wait(fc_thread *thread)
70{
71 int *return_value = NULL;
72
73 thrd_join(*thread, return_value);
74}
75
76/*******************************************************************/
79void fc_init_mutex(fc_mutex *mutex)
80{
81 mtx_init(mutex, mtx_plain|mtx_recursive);
82}
83
84/*******************************************************************/
87void fc_destroy_mutex(fc_mutex *mutex)
88{
89 mtx_destroy(mutex);
90}
91
92/*******************************************************************/
95void fc_allocate_mutex(fc_mutex *mutex)
96{
97 mtx_lock(mutex);
98}
99
100/*******************************************************************/
103void fc_release_mutex(fc_mutex *mutex)
104{
105 mtx_unlock(mutex);
106}
107
108/*******************************************************************/
111void fc_thread_cond_init(fc_thread_cond *cond)
112{
113 cnd_init(cond);
114}
115
116/*******************************************************************/
119void fc_thread_cond_destroy(fc_thread_cond *cond)
120{
121 cnd_destroy(cond);
122}
123
124/*******************************************************************/
127void fc_thread_cond_wait(fc_thread_cond *cond, fc_mutex *mutex)
128{
129 cnd_wait(cond, mutex);
130}
131
132/*******************************************************************/
135void fc_thread_cond_signal(fc_thread_cond *cond)
136{
137 cnd_signal(cond);
138}
139
140#elif defined(FREECIV_HAVE_PTHREAD)
141
142struct fc_thread_wrap_data {
143 void *arg;
144 void (*func)(void *arg);
145};
146
147/*******************************************************************/
151static void *fc_thread_wrapper(void *arg)
152{
153 struct fc_thread_wrap_data *data = (struct fc_thread_wrap_data *) arg;
154
155 data->func(data->arg);
156
157 free(data);
158
159 return NULL;
160}
161
162/*******************************************************************/
165int fc_thread_start(fc_thread *thread, void (*function) (void *arg),
166 void *arg)
167{
168 int ret;
169 pthread_attr_t attr;
170
171 /* Freed by child thread once it's finished with data */
172 struct fc_thread_wrap_data *data = fc_malloc(sizeof(*data));
173
174 data->arg = arg;
175 data->func = function;
176
177 /* Explicitly set thread as joinable to maximize portability
178 between pthread implementations */
179 pthread_attr_init(&attr);
180 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
181
182 ret = pthread_create(thread, &attr, &fc_thread_wrapper, data);
183
184 pthread_attr_destroy(&attr);
185
186 return ret;
187}
188
189/*******************************************************************/
192void fc_thread_wait(fc_thread *thread)
193{
194 void **return_value = NULL;
195
196 pthread_join(*thread, return_value);
197}
198
199/*******************************************************************/
202void fc_init_mutex(fc_mutex *mutex)
203{
204 pthread_mutexattr_t attr;
205
206 pthread_mutexattr_init(&attr);
207 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
208
209 pthread_mutex_init(mutex, &attr);
210
211 pthread_mutexattr_destroy(&attr);
212}
213
214/*******************************************************************/
217void fc_destroy_mutex(fc_mutex *mutex)
218{
219 pthread_mutex_destroy(mutex);
220}
221
222/*******************************************************************/
225void fc_allocate_mutex(fc_mutex *mutex)
226{
227 pthread_mutex_lock(mutex);
228}
229
230/*******************************************************************/
233void fc_release_mutex(fc_mutex *mutex)
234{
235 pthread_mutex_unlock(mutex);
236}
237
238/*******************************************************************/
241void fc_thread_cond_init(fc_thread_cond *cond)
242{
243 pthread_cond_init(cond, NULL);
244}
245
246/*******************************************************************/
249void fc_thread_cond_destroy(fc_thread_cond *cond)
250{
251 pthread_cond_destroy(cond);
252}
253
254/*******************************************************************/
257void fc_thread_cond_wait(fc_thread_cond *cond, fc_mutex *mutex)
258{
259 pthread_cond_wait(cond, mutex);
260}
261
262/*******************************************************************/
265void fc_thread_cond_signal(fc_thread_cond *cond)
266{
267 pthread_cond_signal(cond);
268}
269
270#elif defined(FREECIV_HAVE_WINTHREADS)
271
272struct fc_thread_wrap_data {
273 void *arg;
274 void (*func)(void *arg);
275};
276
277/*******************************************************************/
281static DWORD WINAPI fc_thread_wrapper(LPVOID arg)
282{
283 struct fc_thread_wrap_data *data = (struct fc_thread_wrap_data *) arg;
284
285 data->func(data->arg);
286
287 free(data);
288
289 return 0;
290}
291
292/*******************************************************************/
295int fc_thread_start(fc_thread *thread, void (*function) (void *arg), void *arg)
296{
297 /* Freed by child thread once it's finished with data */
298 struct fc_thread_wrap_data *data = fc_malloc(sizeof(*data));
299
300 data->arg = arg;
301 data->func = function;
302
303 *thread = CreateThread(NULL, 0, &fc_thread_wrapper, data, 0, NULL);
304
305 if (*thread == NULL) {
306 return 1;
307 }
308
309 return 0;
310}
311
312/*******************************************************************/
315void fc_thread_wait(fc_thread *thread)
316{
317 DWORD exit_code;
318
319 GetExitCodeThread(*thread, &exit_code);
320
321 while (exit_code == STILL_ACTIVE) {
322 fc_usleep(1000);
323 GetExitCodeThread(*thread, &exit_code);
324 }
325
326 CloseHandle(*thread);
327}
328
329/*******************************************************************/
332void fc_init_mutex(fc_mutex *mutex)
333{
334 *mutex = CreateMutex(NULL, FALSE, NULL);
335}
336
337/*******************************************************************/
340void fc_destroy_mutex(fc_mutex *mutex)
341{
342 CloseHandle(*mutex);
343}
344
345/*******************************************************************/
348void fc_allocate_mutex(fc_mutex *mutex)
349{
350 WaitForSingleObject(*mutex, INFINITE);
351}
352
353/*******************************************************************/
356void fc_release_mutex(fc_mutex *mutex)
357{
358 ReleaseMutex(*mutex);
359}
360
361/* TODO: Windows thread condition variable support.
362 * Currently related functions are always dummy ones below
363 * (see #ifndef FREECIV_HAVE_THREAD_COND) */
364
365#else /* No thread implementation */
366
367#error "No working thread implementation"
368
369#endif /* FREECIV_HAVE_PTHREAD || FREECIV_HAVE_WINTHREADS */
370
371
372#ifndef FREECIV_HAVE_THREAD_COND
373
374/* Dummy thread condition variable functions */
375
376/*******************************************************************/
379 void fc_thread_cond_init(fc_thread_cond *cond)
380{}
381
382/*******************************************************************/
385 void fc_thread_cond_destroy(fc_thread_cond *cond)
386{}
387
388/*******************************************************************/
391 void fc_thread_cond_wait(fc_thread_cond *cond, fc_mutex *mutex)
392{}
393
394/*******************************************************************/
397 void fc_thread_cond_signal(fc_thread_cond *cond)
398{}
399
400#endif /* !FREECIV_HAVE_THREAD_COND */
401
402/*******************************************************************/
405 bool has_thread_cond_impl(void)
406{
407#ifdef FREECIV_HAVE_THREAD_COND
408 return TRUE;
409#else
410 return FALSE;
411#endif
412}
fc_thread_cond_destroy
void fc_thread_cond_destroy(fc_thread_cond *cond)
Definition fcthread.c:385
fc_thread_cond_signal
void fc_thread_cond_signal(fc_thread_cond *cond)
Definition fcthread.c:397
fc_thread_cond_wait
void fc_thread_cond_wait(fc_thread_cond *cond, fc_mutex *mutex)
Definition fcthread.c:391
has_thread_cond_impl
bool has_thread_cond_impl(void)
Definition fcthread.c:405
fc_thread_cond_init
void fc_thread_cond_init(fc_thread_cond *cond)
Definition fcthread.c:379
fcthread.h
fc_thread_start
int fc_thread_start(fc_thread *thread, void(*function)(void *arg), void *arg)
fc_allocate_mutex
void fc_allocate_mutex(fc_mutex *mutex)
fc_release_mutex
void fc_release_mutex(fc_mutex *mutex)
fc_thread_wait
void fc_thread_wait(fc_thread *thread)
fc_destroy_mutex
void fc_destroy_mutex(fc_mutex *mutex)
fc_init_mutex
void fc_init_mutex(fc_mutex *mutex)
func
get_token_fn_t func
Definition inputfile.c:128
log.h
mem.h
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
fc_usleep
void fc_usleep(unsigned long usec)
Definition support.c:640
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47