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)
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 ***********************************************************************/
15 #include <fc_config.h>
27 struct fc_thread_wrap_data
{
29 void (*func
)(void *arg
);
32 /**********************************************************************
33 Wrapper which fingerprint matches one required by pthread_create().
34 Calls function which matches fingerprint required by fc_thread_start()
35 ***********************************************************************/
36 static void *fc_thread_wrapper(void *arg
)
38 struct fc_thread_wrap_data
*data
= (struct fc_thread_wrap_data
*) arg
;
40 data
->func(data
->arg
);
47 /**********************************************************************
49 ***********************************************************************/
50 int fc_thread_start(fc_thread
*thread
, void (*function
) (void *arg
),
56 /* Freed by child thread once it's finished with data */
57 struct fc_thread_wrap_data
*data
= fc_malloc(sizeof(*data
));
60 data
->func
= function
;
62 /* Explicitly set thread as joinable to maximize portability
63 between pthread implementations */
64 pthread_attr_init(&attr
);
65 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_JOINABLE
);
67 ret
= pthread_create(thread
, &attr
, &fc_thread_wrapper
, data
);
69 pthread_attr_destroy(&attr
);
74 /**********************************************************************
75 Wait for thread to finish
76 ***********************************************************************/
77 void fc_thread_wait(fc_thread
*thread
)
79 void **return_value
= NULL
;
81 pthread_join(*thread
, return_value
);
84 /**********************************************************************
86 ***********************************************************************/
87 void fc_init_mutex(fc_mutex
*mutex
)
89 pthread_mutexattr_t attr
;
91 pthread_mutexattr_init(&attr
);
92 pthread_mutexattr_settype(&attr
, PTHREAD_MUTEX_RECURSIVE
);
94 pthread_mutex_init(mutex
, &attr
);
96 pthread_mutexattr_destroy(&attr
);
99 /**********************************************************************
101 ***********************************************************************/
102 void fc_destroy_mutex(fc_mutex
*mutex
)
104 pthread_mutex_destroy(mutex
);
107 /**********************************************************************
109 ***********************************************************************/
110 void fc_allocate_mutex(fc_mutex
*mutex
)
112 pthread_mutex_lock(mutex
);
115 /**********************************************************************
117 ***********************************************************************/
118 void fc_release_mutex(fc_mutex
*mutex
)
120 pthread_mutex_unlock(mutex
);
123 /**********************************************************************
125 ***********************************************************************/
126 void fc_thread_cond_init(fc_thread_cond
*cond
)
128 pthread_cond_init(cond
, NULL
);
131 /**********************************************************************
133 ***********************************************************************/
134 void fc_thread_cond_destroy(fc_thread_cond
*cond
)
136 pthread_cond_destroy(cond
);
139 /**********************************************************************
140 Wait for condition to be fulfilled
141 ***********************************************************************/
142 void fc_thread_cond_wait(fc_thread_cond
*cond
, fc_mutex
*mutex
)
144 pthread_cond_wait(cond
, mutex
);
147 /**********************************************************************
148 Signal other thread to continue on fulfilled condition
149 ***********************************************************************/
150 void fc_thread_cond_signal(fc_thread_cond
*cond
)
152 pthread_cond_signal(cond
);
155 #elif defined(HAVE_WINTHREADS)
157 struct fc_thread_wrap_data
{
159 void (*func
)(void *arg
);
162 /**********************************************************************
163 Wrapper which fingerprint matches one required by CreateThread().
164 Calls function which matches fingerprint required by fc_thread_start()
165 ***********************************************************************/
166 static DWORD WINAPI
fc_thread_wrapper(LPVOID arg
)
168 struct fc_thread_wrap_data
*data
= (struct fc_thread_wrap_data
*) arg
;
170 data
->func(data
->arg
);
177 /**********************************************************************
179 ***********************************************************************/
180 int fc_thread_start(fc_thread
*thread
, void (*function
) (void *arg
), void *arg
)
182 /* Freed by child thread once it's finished with data */
183 struct fc_thread_wrap_data
*data
= fc_malloc(sizeof(*data
));
186 data
->func
= function
;
188 *thread
= CreateThread(NULL
, 0, &fc_thread_wrapper
, data
, 0, NULL
);
190 if (*thread
== NULL
) {
197 /**********************************************************************
198 Wait for thread to finish
199 ***********************************************************************/
200 void fc_thread_wait(fc_thread
*thread
)
204 GetExitCodeThread(*thread
, &exit_code
);
206 while (exit_code
== STILL_ACTIVE
) {
208 GetExitCodeThread(*thread
, &exit_code
);
211 CloseHandle(*thread
);
214 /**********************************************************************
216 ***********************************************************************/
217 void fc_init_mutex(fc_mutex
*mutex
)
219 *mutex
= CreateMutex(NULL
, FALSE
, NULL
);
222 /**********************************************************************
224 ***********************************************************************/
225 void fc_destroy_mutex(fc_mutex
*mutex
)
230 /**********************************************************************
232 ***********************************************************************/
233 void fc_allocate_mutex(fc_mutex
*mutex
)
235 WaitForSingleObject(*mutex
, INFINITE
);
238 /**********************************************************************
240 ***********************************************************************/
241 void fc_release_mutex(fc_mutex
*mutex
)
243 ReleaseMutex(*mutex
);
246 /* TODO: Windows thread condition variable support.
247 * Currently related functions are always dummy ones below
248 * (see #ifndef HAVE_THREAD_COND) */
250 #else /* No thread implementation */
252 #error "No working thread implementation"
254 #endif /* HAVE_PTHREAD || HAVE_WINTHREADS */
257 #ifndef HAVE_THREAD_COND
259 /* Dummy thread condition variable functions */
261 /**********************************************************************
262 Dummy fc_thread_cond_init()
263 ***********************************************************************/
264 void fc_thread_cond_init(fc_thread_cond
*cond
)
267 /**********************************************************************
268 Dummy fc_thread_cond_destroy()
269 ***********************************************************************/
270 void fc_thread_cond_destroy(fc_thread_cond
*cond
)
273 /**********************************************************************
274 Dummy fc_thread_cond_wait()
275 ***********************************************************************/
276 void fc_thread_cond_wait(fc_thread_cond
*cond
, fc_mutex
*mutex
)
279 /**********************************************************************
280 Dummy fc_thread_cond_signal()
281 ***********************************************************************/
282 void fc_thread_cond_signal(fc_thread_cond
*cond
)
285 #endif /* !HAVE_THREAD_COND */
287 /**********************************************************************
288 Has freeciv thread condition variable implementation
289 ***********************************************************************/
290 bool has_thread_cond_impl(void)
292 #ifdef HAVE_THREAD_COND