Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -76,11 +76,11 @@ #endif #ifndef OF_AMIGAOS # define closeHandle(h) close(h) #else -struct of_file_handle { +static struct of_file_handle { of_file_handle_t previous, next; BPTR handle; bool append; } *firstHandle = NULL; Index: src/once.m ================================================================== --- src/once.m +++ src/once.m @@ -15,10 +15,12 @@ * file. */ #include "config.h" +#include + #import "once.h" #ifdef OF_AMIGAOS # include #endif @@ -31,16 +33,20 @@ void of_once(of_once_t *control, void (*func)(void)) { #if !defined(OF_HAVE_THREADS) if (*control == 0) { - *control = 1; func(); + *control = 1; } #elif defined(OF_HAVE_PTHREADS) pthread_once(control, func); #elif defined(OF_HAVE_ATOMIC_OPS) + /* Avoid atomic operations in case it's already done. */ + if (*control == 2) + return; + if (of_atomic_int_cmpswap(control, 0, 1)) { func(); of_memory_barrier(); @@ -47,18 +53,35 @@ of_atomic_int_inc(control); } else while (*control == 1) of_thread_yield(); #elif defined(OF_AMIGAOS) + bool run = false; + + /* Avoid Forbid() in case it's already done. */ + if (*control == 2) + return; + Forbid(); - @try { - if (*control == 0) { - *control = 1; - func(); + + switch (*control) { + case 0: + *control = 1; + run = true; + break; + case 1: + while (*control == 1) { + Permit(); + Forbid(); } - } @finally { - Permit(); + } + + Permit(); + + if (run) { + func(); + *control = 2; } #else # error No of_once available #endif }