ObjFW
Loading...
Searching...
No Matches
OFOnce.m
1/*
2 * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
3 *
4 * All rights reserved.
5 *
6 * This file is part of ObjFW. It may be distributed under the terms of the
7 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
8 * the packaging of this file.
9 *
10 * Alternatively, it may be distributed under the terms of the GNU General
11 * Public License, either version 2 or 3, which can be found in the file
12 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
13 * file.
14 */
15
16#include "config.h"
17
18#include <stdbool.h>
19
20#import "OFOnce.h"
21#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_ATOMIC_OPS)
22# import "OFAtomic.h"
23# import "OFPlainMutex.h"
24#endif
25
26#ifdef OF_AMIGAOS
27# define Class IntuitionClass
28# include <proto/exec.h>
29# undef Class
30#endif
31
32void
33OFOnce(OFOnceControl *control, void (*function)(void))
34{
35#if !defined(OF_HAVE_THREADS)
36 if (*control == 0) {
37 function();
38 *control = 1;
39 }
40#elif defined(OF_HAVE_PTHREADS)
41 pthread_once(control, function);
42#elif defined(OF_HAVE_ATOMIC_OPS)
43 /* Avoid atomic operations in case it's already done. */
44 if (*control == 2)
45 return;
46
47 if (OFAtomicIntCompareAndSwap(control, 0, 1)) {
48 function();
49
50 OFMemoryBarrier();
51
52 OFAtomicIntIncrease(control);
53 } else
54 while (*control == 1)
55 OFYieldThread();
56#elif defined(OF_AMIGAOS)
57 bool run = false;
58
59 /* Avoid Forbid() in case it's already done. */
60 if (*control == 2)
61 return;
62
63 Forbid();
64
65 switch (*control) {
66 case 0:
67 *control = 1;
68 run = true;
69 break;
70 case 1:
71 while (*control == 1) {
72 Permit();
73 Forbid();
74 }
75 }
76
77 Permit();
78
79 if (run) {
80 function();
81 *control = 2;
82 }
83#else
84# error No OFOnce available
85#endif
86}
void OFOnce(OFOnceControl *control, OFOnceFunction function)
Executes the specified function exactly once in the application's lifetime, even in a multi-threaded ...
Definition OFOnce.m:33