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
/* Avoid atomic operations in case it's already done. */
48
if
(*control == 2)
49
return
;
50
51
if
(OFAtomicIntCompareAndSwap(control, 0, 1)) {
52
OFAcquireMemoryBarrier();
53
54
function
();
55
OFAtomicIntIncrease(control);
56
57
OFReleaseMemoryBarrier();
58
}
else
59
while
(*control == 1)
60
OFYieldThread
();
61
#elif defined(OF_AMIGAOS)
62
bool
run =
false
;
63
64
/* Avoid Forbid() in case it's already done. */
65
if
(*control == 2)
66
return
;
67
68
Forbid();
69
70
switch
(*control) {
71
case
0:
72
*control = 1;
73
run =
true
;
74
break
;
75
case
1:
76
while
(*control == 1) {
77
Permit();
78
Forbid();
79
}
80
}
81
82
Permit();
83
84
if
(run) {
85
function
();
86
*control = 2;
87
}
88
#else
89
# error No OFOnce available
90
#endif
91
}
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