ObjFW
Toggle main menu visibility
Loading...
Searching...
No Matches
OFOnce.m
1
/*
2
* Copyright (c) 2008-2026 Jonathan Schleifer <js@nil.im>
3
*
4
* All rights reserved.
5
*
6
* This program is free software: you can redistribute it and/or modify it
7
* under the terms of the GNU Lesser General Public License version 3.0 only,
8
* as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13
* version 3.0 for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public License
16
* version 3.0 along with this program. If not, see
17
* <https://www.gnu.org/licenses/>.
18
*/
19
20
#include "config.h"
21
22
#include <stdbool.h>
23
24
#import "
OFOnce.h
"
25
#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_ATOMIC_OPS)
26
# import "OFAtomic.h"
27
# import "
OFPlainMutex.h
"
28
#endif
29
30
#ifdef OF_AMIGAOS
31
# define Class IntuitionClass
32
# include <proto/exec.h>
33
# undef Class
34
#endif
35
36
void
37
OFOnce
(OFOnceControl *control,
void
(*
function
)(
void
))
38
{
39
#if !defined(OF_HAVE_THREADS)
40
if
(*control == 0) {
41
function
();
42
*control = 1;
43
}
44
#elif defined(OF_HAVE_PTHREADS)
45
pthread_once(control,
function
);
46
#elif defined(OF_HAVE_ATOMIC_OPS)
47
if
(*control == 2) {
48
OFAcquireMemoryBarrier();
49
return
;
50
}
51
52
if
(OFAtomicIntCompareAndSwap(control, 0, 1)) {
53
function
();
54
55
OFReleaseMemoryBarrier();
56
57
OFAtomicIntIncrease(control);
58
}
else
{
59
while
(*control == 1)
60
OFYieldThread
();
61
62
OFAcquireMemoryBarrier();
63
}
64
#elif defined(OF_AMIGAOS)
65
bool
run =
false
;
66
67
/* Avoid Forbid() in case it's already done. */
68
if
(*control == 2)
69
return
;
70
71
Forbid();
72
73
switch
(*control) {
74
case
0:
75
*control = 1;
76
run =
true
;
77
break
;
78
case
1:
79
while
(*control == 1) {
80
Permit();
81
Forbid();
82
}
83
}
84
85
Permit();
86
87
if
(run) {
88
function
();
89
*control = 2;
90
}
91
#else
92
# error No OFOnce available
93
#endif
94
}
OFOnce.h
OFOnce
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:37
OFPlainMutex.h
OFYieldThread
static OF_INLINE void OFYieldThread(void)
Yield the current thread, indicating to the OS that another thread should execute instead.
Definition
OFPlainMutex.h:171
src
OFOnce.m
Generated by
1.17.0