ObjFW  Diff

Differences From Artifact [7bbaf6acd2]:

To Artifact [23ee43131c]:


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "objfw-defs.h"

#if !defined(OF_HAVE_THREADS) || \
    (!defined(OF_HAVE_PTHREADS) && !defined(_WIN32))
# error No threads available!
#endif

#include <math.h>

#import "OFObject.h"








|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "objfw-defs.h"

#if !defined(OF_HAVE_THREADS) || \
	(!defined(OF_HAVE_PTHREADS) && !defined(_WIN32))
# error No threads available!
#endif

#include <math.h>

#import "OFObject.h"

38
39
40
41
42
43
44


45
46
47
48
49
50
51
typedef HANDLE of_thread_t;
typedef DWORD of_tlskey_t;
typedef CRITICAL_SECTION of_mutex_t;
typedef struct {
	HANDLE event;
	int count;
} of_condition_t;


#endif

#if defined(OF_HAVE_ATOMIC_OPS)
# import "atomic.h"
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)







>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
typedef HANDLE of_thread_t;
typedef DWORD of_tlskey_t;
typedef CRITICAL_SECTION of_mutex_t;
typedef struct {
	HANDLE event;
	int count;
} of_condition_t;
#else
# error No threads available!
#endif

#if defined(OF_HAVE_ATOMIC_OPS)
# import "atomic.h"
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
65
66
67
68
69
70
71



72
73
74
75
76
77
78
79
80
81
82
83
84


85
86
87
88
89
90
91

#if defined(OF_HAVE_PTHREADS)
# define of_thread_is_current(t) pthread_equal(t, pthread_self())
# define of_thread_current pthread_self
#elif defined(_WIN32)
# define of_thread_is_current(t) (t == GetCurrentThread())
# define of_thread_current GetCurrentThread



#endif

static OF_INLINE bool
of_thread_new(of_thread_t *thread, id (*function)(id), id data)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_create(thread, NULL, (void*(*)(void*))function,
	    (__bridge void*)data);
#elif defined(_WIN32)
	*thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)function,
	    (__bridge void*)data, 0, NULL);

	return (thread != NULL);


#endif
}

static OF_INLINE bool
of_thread_join(of_thread_t thread)
{
#if defined(OF_HAVE_PTHREADS)







>
>
>













>
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

#if defined(OF_HAVE_PTHREADS)
# define of_thread_is_current(t) pthread_equal(t, pthread_self())
# define of_thread_current pthread_self
#elif defined(_WIN32)
# define of_thread_is_current(t) (t == GetCurrentThread())
# define of_thread_current GetCurrentThread
#else
# error of_thread_is_current not implemented!
# error of_thread_current not implemented!
#endif

static OF_INLINE bool
of_thread_new(of_thread_t *thread, id (*function)(id), id data)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_create(thread, NULL, (void*(*)(void*))function,
	    (__bridge void*)data);
#elif defined(_WIN32)
	*thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)function,
	    (__bridge void*)data, 0, NULL);

	return (thread != NULL);
#else
# error of_thread_new not implemented!
#endif
}

static OF_INLINE bool
of_thread_join(of_thread_t thread)
{
#if defined(OF_HAVE_PTHREADS)
102
103
104
105
106
107
108


109
110
111
112
113
114
115
116
117
118
119


120
121
122
123
124
125
126
127
128
129


130
131
132
133
134
135
136
137
138
139
140


141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
160
161
162


163
164
165
166
167
168
169
170
171
172


173
174
175
176
177
178
179
180
181
182
183


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198


199
200
201
202
203
204
205
#elif defined(_WIN32)
	if (WaitForSingleObject(thread, INFINITE))
		return false;

	CloseHandle(thread);

	return true;


#endif
}

static OF_INLINE bool
of_thread_detach(of_thread_t thread)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_detach(thread);
#elif defined(_WIN32)
	/* FIXME */
	return true;


#endif
}

static OF_INLINE void
of_thread_exit(void)
{
#if defined(OF_HAVE_PTHREADS)
	pthread_exit(NULL);
#elif defined(_WIN32)
	ExitThread(0);


#endif
}

static OF_INLINE bool
of_mutex_new(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_init(mutex, NULL);
#elif defined(_WIN32)
	InitializeCriticalSection(mutex);
	return true;


#endif
}

static OF_INLINE bool
of_mutex_free(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_destroy(mutex);
#elif defined(_WIN32)
	DeleteCriticalSection(mutex);
	return true;


#endif
}

static OF_INLINE bool
of_mutex_lock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_lock(mutex);
#elif defined(_WIN32)
	EnterCriticalSection(mutex);
	return true;


#endif
}

static OF_INLINE bool
of_mutex_trylock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_trylock(mutex);
#elif defined(_WIN32)
	return TryEnterCriticalSection(mutex);


#endif
}

static OF_INLINE bool
of_mutex_unlock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_unlock(mutex);
#elif defined(_WIN32)
	LeaveCriticalSection(mutex);
	return true;


#endif
}

static OF_INLINE bool
of_condition_new(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_init(condition, NULL);
#elif defined(_WIN32)
	condition->count = 0;

	if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
		return false;

	return true;


#endif
}

static OF_INLINE bool
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)







>
>











>
>










>
>











>
>











>
>











>
>










>
>











>
>















>
>







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#elif defined(_WIN32)
	if (WaitForSingleObject(thread, INFINITE))
		return false;

	CloseHandle(thread);

	return true;
#else
# error of_thread_join not implemented!
#endif
}

static OF_INLINE bool
of_thread_detach(of_thread_t thread)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_detach(thread);
#elif defined(_WIN32)
	/* FIXME */
	return true;
#else
# error of_thread_detach not implemented!
#endif
}

static OF_INLINE void
of_thread_exit(void)
{
#if defined(OF_HAVE_PTHREADS)
	pthread_exit(NULL);
#elif defined(_WIN32)
	ExitThread(0);
#else
# error of_thread_exit not implemented!
#endif
}

static OF_INLINE bool
of_mutex_new(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_init(mutex, NULL);
#elif defined(_WIN32)
	InitializeCriticalSection(mutex);
	return true;
#else
# error of_mutex_new not implemented!
#endif
}

static OF_INLINE bool
of_mutex_free(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_destroy(mutex);
#elif defined(_WIN32)
	DeleteCriticalSection(mutex);
	return true;
#else
# error of_mutex_free not implemented!
#endif
}

static OF_INLINE bool
of_mutex_lock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_lock(mutex);
#elif defined(_WIN32)
	EnterCriticalSection(mutex);
	return true;
#else
# error of_mutex_lock not implemented!
#endif
}

static OF_INLINE bool
of_mutex_trylock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_trylock(mutex);
#elif defined(_WIN32)
	return TryEnterCriticalSection(mutex);
#else
# error of_mutex_trylock not implemented!
#endif
}

static OF_INLINE bool
of_mutex_unlock(of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_mutex_unlock(mutex);
#elif defined(_WIN32)
	LeaveCriticalSection(mutex);
	return true;
#else
# error of_mutex_unlock not implemented!
#endif
}

static OF_INLINE bool
of_condition_new(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_init(condition, NULL);
#elif defined(_WIN32)
	condition->count = 0;

	if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
		return false;

	return true;
#else
# error of_condition_new not implemented!
#endif
}

static OF_INLINE bool
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
217
218
219
220
221
222
223


224
225
226
227
228
229
230

	of_atomic_dec_int(&condition->count);

	if (!of_mutex_lock(mutex))
		return false;

	return true;


#endif
}

static OF_INLINE bool
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{







>
>







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

	of_atomic_dec_int(&condition->count);

	if (!of_mutex_lock(mutex))
		return false;

	return true;
#else
# error of_condition_wait not implemented!
#endif
}

static OF_INLINE bool
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    of_time_interval_t timeout)
{
249
250
251
252
253
254
255


256
257
258
259
260
261
262
263
264
265


266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281


282
283
284
285
286
287
288
289
290
291
292
293
294


295
296
297
298
299
300
301
302
303
304


305
306
307
308
309
310
311
312
313
314


315
316
317
318
319
320
321
322
323
324


325
326
327
328
329
330
331
332
333
334


335
336
337
338
339
340
341

	of_atomic_dec_int(&condition->count);

	if (!of_mutex_lock(mutex))
		return false;

	return true;


#endif
}

static OF_INLINE bool
of_condition_signal(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_signal(condition);
#elif defined(_WIN32)
	return SetEvent(condition->event);


#endif
}

static OF_INLINE bool
of_condition_broadcast(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_broadcast(condition);
#elif defined(_WIN32)
	int i;

	for (i = 0; i < condition->count; i++)
		if (!SetEvent(condition->event))
			return false;

	return true;


#endif
}

static OF_INLINE bool
of_condition_free(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_destroy(condition);
#elif defined(_WIN32)
	if (condition->count)
		return false;

	return CloseHandle(condition->event);


#endif
}

static OF_INLINE bool
of_tlskey_new(of_tlskey_t *key)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_key_create(key, NULL);
#elif defined(_WIN32)
	return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);


#endif
}

static OF_INLINE void*
of_tlskey_get(of_tlskey_t key)
{
#if defined(OF_HAVE_PTHREADS)
	return pthread_getspecific(key);
#elif defined(_WIN32)
	return TlsGetValue(key);


#endif
}

static OF_INLINE bool
of_tlskey_set(of_tlskey_t key, void *ptr)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_setspecific(key, ptr);
#elif defined(_WIN32)
	return TlsSetValue(key, ptr);


#endif
}

static OF_INLINE bool
of_tlskey_free(of_tlskey_t key)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_key_delete(key);
#elif defined(_WIN32)
	return TlsFree(key);


#endif
}

static OF_INLINE bool
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)







>
>










>
>
















>
>













>
>










>
>










>
>










>
>










>
>







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

	of_atomic_dec_int(&condition->count);

	if (!of_mutex_lock(mutex))
		return false;

	return true;
#else
# error of_condition_timed_wait not implemented!
#endif
}

static OF_INLINE bool
of_condition_signal(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_signal(condition);
#elif defined(_WIN32)
	return SetEvent(condition->event);
#else
# error of_condition_signal not implemented!
#endif
}

static OF_INLINE bool
of_condition_broadcast(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_broadcast(condition);
#elif defined(_WIN32)
	int i;

	for (i = 0; i < condition->count; i++)
		if (!SetEvent(condition->event))
			return false;

	return true;
#else
# error of_condition_broadcast not implemented!
#endif
}

static OF_INLINE bool
of_condition_free(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_destroy(condition);
#elif defined(_WIN32)
	if (condition->count)
		return false;

	return CloseHandle(condition->event);
#else
# error of_condition_free not implemented!
#endif
}

static OF_INLINE bool
of_tlskey_new(of_tlskey_t *key)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_key_create(key, NULL);
#elif defined(_WIN32)
	return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);
#else
# error of_tlskey_new not implemented!
#endif
}

static OF_INLINE void*
of_tlskey_get(of_tlskey_t key)
{
#if defined(OF_HAVE_PTHREADS)
	return pthread_getspecific(key);
#elif defined(_WIN32)
	return TlsGetValue(key);
#else
# error of_tlskey_get not implemented!
#endif
}

static OF_INLINE bool
of_tlskey_set(of_tlskey_t key, void *ptr)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_setspecific(key, ptr);
#elif defined(_WIN32)
	return TlsSetValue(key, ptr);
#else
# error of_tlskey_set not implemented!
#endif
}

static OF_INLINE bool
of_tlskey_free(of_tlskey_t key)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_key_delete(key);
#elif defined(_WIN32)
	return TlsFree(key);
#else
# error of_tlskey_free not implemented!
#endif
}

static OF_INLINE bool
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)