| /** |
| * This file has no copyright assigned and is placed in the Public Domain. |
| * This file is part of the mingw-w64 runtime package. |
| * No warranty is given; refer to the file DISCLAIMER.PD within this package. |
| */ |
| |
| #include <process.h> |
| #include <stdlib.h> |
| |
| #define _EXIT_LOCK1 8 |
| |
| void __cdecl _lock (int _File); |
| void __cdecl _unlock (int _File); |
| |
| int __cdecl _initialize_onexit_table(_onexit_table_t *table) |
| { |
| if (!table) return -1; |
| table->_first = table->_last = table->_end = NULL; |
| return 0; |
| } |
| |
| int __cdecl _register_onexit_function(_onexit_table_t *table, _onexit_t func) |
| { |
| if (!table) return -1; |
| |
| _lock(_EXIT_LOCK1); |
| |
| if (!table->_first) { |
| table->_first = calloc(32, sizeof(void*)); |
| if (!table->_first) { |
| _unlock(_EXIT_LOCK1); |
| return -1; |
| } |
| table->_last = table->_first; |
| table->_end = table->_first + 32; |
| } |
| |
| if (table->_last == table->_end) { |
| size_t len = table->_end - table->_first; |
| _PVFV *new_buf = realloc(table->_first, len * sizeof(void*) * 2); |
| if (!new_buf) { |
| _unlock(_EXIT_LOCK1); |
| return -1; |
| } |
| table->_first = new_buf; |
| table->_last = new_buf + len; |
| table->_end = new_buf + len * 2; |
| } |
| |
| *table->_last++ = (_PVFV)func; |
| _unlock(_EXIT_LOCK1); |
| return 0; |
| } |
| |
| int __cdecl _execute_onexit_table(_onexit_table_t *table) |
| { |
| _PVFV *first, *last; |
| |
| _lock(_EXIT_LOCK1); |
| first = table->_first; |
| last = table->_last; |
| _initialize_onexit_table(table); |
| _unlock(_EXIT_LOCK1); |
| |
| if (!first) return 0; |
| |
| while (--last >= first) |
| if (*last) |
| (**last)(); |
| |
| free(first); |
| return 0; |
| } |
| |
| typeof(_initialize_onexit_table) *__MINGW_IMP_SYMBOL(_initialize_onexit_table) = _initialize_onexit_table; |
| typeof(_register_onexit_function) *__MINGW_IMP_SYMBOL(_register_onexit_function) = _register_onexit_function; |
| typeof(_execute_onexit_table) *__MINGW_IMP_SYMBOL(_execute_onexit_table) = _execute_onexit_table; |