ObjFW  Diff

Differences From Artifact [ba948db4c9]:

To Artifact [c5163894df]:


63
64
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

92
93
94
95
96

97
98
99
100

101
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
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
231
232
233
234
235
236
237
238
239

240
241

242
243
244
245

246
247
248
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
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

385
386
387

388
389
390

391
392
393

394
395

396
397
398
399
400
401
402
403

404
405
406
407

408
409
410

411
412

413
414
415

416
417
418
419
420
421
422
423



424
425
426
427

428
429
430
431

432
433
434

435
436
437

438
439
440
441
442
443
444
445



446
447
448
449

450
451
452
453

454
455
456

457
458
459

460
461
462
463
464
465
466
467



468
469
470
471

472
473
474

475
476

477
478
479

480
481
482
483

484
485
486

487
488

489
490
63
64
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
92
93
94
95

96
97
98
99

100
101
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
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
231
232
233
234
235
236
237
238

239
240

241
242
243
244

245
246
247
248
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
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
385
386

387
388
389

390
391
392

393
394

395
396
397
398
399
400
401
402

403
404
405
406

407
408
409

410
411

412
413
414

415
416
417
418
419
420
421


422
423
424
425
426
427

428
429
430
431

432
433
434

435
436
437

438
439
440
441
442
443
444


445
446
447
448
449
450

451
452
453
454

455
456
457

458
459
460

461
462
463
464
465
466
467


468
469
470
471
472
473

474
475
476

477
478

479
480
481

482
483
484
485

486
487
488

489
490

491
492
493







-
+













-
+






-
+




-
+



-
+



-
+






-
+













-
+






-
+



-
+






-
+



-
+






-
+



-
+









-
+






-
+



-
+








-
+

-
+



-
+






-
+





-
+





-
+

-
+



-
+









-
+









-
+

-
+



-
+






-
+





-
+



















-
+









-
+









-
+




-
+







-
+











-
+








-
+











-
+







-
+




-
+







-
+



-
+








-
+





-
+


-
+


-
+


-
+

-
+







-
+



-
+


-
+

-
+


-
+






-
-
+
+
+



-
+



-
+


-
+


-
+






-
-
+
+
+



-
+



-
+


-
+


-
+






-
-
+
+
+



-
+


-
+

-
+


-
+



-
+


-
+

-
+


# 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
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
static OF_INLINE bool
of_thread_join(of_thread_t thread)
{
#if defined(OF_HAVE_PTHREADS)
	void *ret;

	if (pthread_join(thread, &ret))
		return NO;
		return false;

	return (ret != PTHREAD_CANCELED);
#elif defined(_WIN32)
	if (WaitForSingleObject(thread, INFINITE))
		return NO;
		return false;

	CloseHandle(thread);

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
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 YES;
	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
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 YES;
	return true;
#endif
}

static OF_INLINE BOOL
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 YES;
	return true;
#endif
}

static OF_INLINE BOOL
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 YES;
	return true;
#endif
}

static OF_INLINE BOOL
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
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 YES;
	return true;
#endif
}

static OF_INLINE BOOL
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 NO;
		return false;

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_wait(condition, mutex);
#elif defined(_WIN32)
	if (!of_mutex_unlock(mutex))
		return NO;
		return false;

	of_atomic_inc_int(&condition->count);

	if (WaitForSingleObject(condition->event, INFINITE) != WAIT_OBJECT_0) {
		of_mutex_lock(mutex);
		return NO;
		return false;
	}

	of_atomic_dec_int(&condition->count);

	if (!of_mutex_lock(mutex))
		return NO;
		return false;

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
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
static OF_INLINE bool
of_condition_broadcast(of_condition_t *condition)
{
#if defined(OF_HAVE_PTHREADS)
	return !pthread_cond_broadcast(condition);
#elif defined(_WIN32)
	size_t i;

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

	return YES;
	return true;
#endif
}

static OF_INLINE BOOL
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 NO;
		return false;

	return CloseHandle(condition->event);
#endif
}

static OF_INLINE BOOL
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
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
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
static OF_INLINE bool
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_init(spinlock, 0);
#else
	return of_mutex_new(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return of_atomic_cmpswap_int(spinlock, 0, 1);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_trylock(spinlock);
#else
	return of_mutex_trylock(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
# if defined(OF_HAVE_SCHED_YIELD) || defined(_WIN32)
	int i;

	for (i = 0; i < OF_SPINCOUNT; i++)
		if (of_spinlock_trylock(spinlock))
			return YES;
			return true;

	while (!of_spinlock_trylock(spinlock))
#  ifndef _WIN32
		sched_yield();
#  else
		Sleep(0);
#  endif
# else
	while (!of_spinlock_trylock(spinlock));
# endif

	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_lock(spinlock);
#else
	return of_mutex_lock(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}

static OF_INLINE BOOL
static OF_INLINE bool
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return YES;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}

#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_new(of_mutex_t *mutex)
{
	pthread_mutexattr_t attr;

	if (pthread_mutexattr_init(&attr))
		return NO;
		return false;

	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
		return NO;
		return false;

	if (pthread_mutex_init(mutex, &attr))
		return NO;
		return false;

	if (pthread_mutexattr_destroy(&attr))
		return NO;
		return false;

	return YES;
	return true;
}

# define of_rmutex_lock of_mutex_lock
# define of_rmutex_trylock of_mutex_trylock
# define of_rmutex_unlock of_mutex_unlock
# define of_rmutex_free of_mutex_free
#else
static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_new(of_rmutex_t *rmutex)
{
	if (!of_mutex_new(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_new(&rmutex->count))
		return NO;
		return false;

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_lock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void*)(count + 1)))
			return NO;
		return YES;
			return false;

		return true;
	}

	if (!of_mutex_lock(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_set(rmutex->count, (void*)1)) {
		of_mutex_unlock(&rmutex->mutex);
		return NO;
		return false;
	}

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void*)(count + 1)))
			return NO;
		return YES;
			return false;

		return true;
	}

	if (!of_mutex_trylock(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_set(rmutex->count, (void*)1)) {
		of_mutex_unlock(&rmutex->mutex);
		return NO;
		return false;
	}

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 1) {
		if (!of_tlskey_set(rmutex->count, (void*)(count - 1)))
			return NO;
		return YES;
			return false;

		return true;
	}

	if (!of_tlskey_set(rmutex->count, (void*)0))
		return NO;
		return false;

	if (!of_mutex_unlock(&rmutex->mutex))
		return NO;
		return false;

	return YES;
	return true;
}

static OF_INLINE BOOL
static OF_INLINE bool
of_rmutex_free(of_rmutex_t *rmutex)
{
	if (!of_mutex_free(&rmutex->mutex))
		return NO;
		return false;

	if (!of_tlskey_free(rmutex->count))
		return NO;
		return false;

	return YES;
	return true;
}
#endif