ucrtbase: Implement _execute_onexit_table().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2016-04-27 09:21:12 +03:00 committed by Alexandre Julliard
parent 0a31f489a6
commit f3465ecbae
4 changed files with 103 additions and 2 deletions

View file

@ -34,7 +34,7 @@
@ cdecl _endthread() ucrtbase._endthread
@ cdecl _endthreadex(long) ucrtbase._endthreadex
@ cdecl _errno() ucrtbase._errno
@ stub _execute_onexit_table
@ cdecl _execute_onexit_table(ptr) ucrtbase._execute_onexit_table
@ cdecl _exit(long) ucrtbase._exit
@ cdecl _fpieee_flt(long ptr ptr) ucrtbase._fpieee_flt
@ cdecl _fpreset() ucrtbase._fpreset

View file

@ -399,6 +399,33 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
return 0;
}
/*********************************************************************
* _execute_onexit_table (UCRTBASE.@)
*/
int CDECL MSVCRT__execute_onexit_table(MSVCRT__onexit_table_t *table)
{
MSVCRT__onexit_t *func;
TRACE("(%p)\n", table);
if (!table)
return -1;
if (!table->_first || table->_first >= table->_last)
return 0;
for (func = table->_last - 1; func >= table->_first; func--)
{
if (*func)
(*func)();
}
MSVCRT_free(table->_first);
memset(table, 0, sizeof(*table));
MSVCRT__initialize_onexit_table(table);
return 0;
}
/*********************************************************************
* _set_purecall_handler (MSVCR71.@)
*/

View file

@ -37,6 +37,7 @@ typedef struct MSVCRT__onexit_table_t
static int (CDECL *p_initialize_onexit_table)(MSVCRT__onexit_table_t *table);
static int (CDECL *p_register_onexit_function)(MSVCRT__onexit_table_t *table, MSVCRT__onexit_t func);
static int (CDECL *p_execute_onexit_table)(MSVCRT__onexit_table_t *table);
static void test__initialize_onexit_table(void)
{
@ -98,8 +99,17 @@ static void test__initialize_onexit_table(void)
table._first, table._last, table._end);
}
static int g_onexit_called;
static int CDECL onexit_func(void)
{
g_onexit_called++;
return 0;
}
static int CDECL onexit_func2(void)
{
ok(g_onexit_called == 0, "got %d\n", g_onexit_called);
g_onexit_called++;
return 0;
}
@ -139,12 +149,75 @@ static void test__register_onexit_function(void)
ok(f != table._last, "got %p, initial %p\n", table._last, f);
}
static void test__execute_onexit_table(void)
{
MSVCRT__onexit_table_t table;
int ret;
if (!p_execute_onexit_table)
{
win_skip("_execute_onexit_table() is not available.\n");
return;
}
ret = p_execute_onexit_table(NULL);
ok(ret == -1, "got %d\n", ret);
memset(&table, 0, sizeof(table));
ret = p_initialize_onexit_table(&table);
ok(ret == 0, "got %d\n", ret);
/* execute empty table */
ret = p_execute_onexit_table(&table);
ok(ret == 0, "got %d\n", ret);
/* same functions registered twice */
ret = p_register_onexit_function(&table, onexit_func);
ok(ret == 0, "got %d\n", ret);
ret = p_register_onexit_function(&table, NULL);
ok(ret == 0, "got %d\n", ret);
ret = p_register_onexit_function(&table, onexit_func);
ok(ret == 0, "got %d\n", ret);
ok(table._first != table._end, "got %p, %p\n", table._first, table._end);
g_onexit_called = 0;
ret = p_execute_onexit_table(&table);
ok(ret == 0, "got %d\n", ret);
ok(g_onexit_called == 2, "got %d\n", g_onexit_called);
ok(table._first == table._end, "got %p, %p\n", table._first, table._end);
/* execute again, table is already empty */
g_onexit_called = 0;
ret = p_execute_onexit_table(&table);
ok(ret == 0, "got %d\n", ret);
ok(g_onexit_called == 0, "got %d\n", g_onexit_called);
/* check call order */
memset(&table, 0, sizeof(table));
ret = p_initialize_onexit_table(&table);
ok(ret == 0, "got %d\n", ret);
ret = p_register_onexit_function(&table, onexit_func);
ok(ret == 0, "got %d\n", ret);
ret = p_register_onexit_function(&table, onexit_func2);
ok(ret == 0, "got %d\n", ret);
g_onexit_called = 0;
ret = p_execute_onexit_table(&table);
ok(ret == 0, "got %d\n", ret);
ok(g_onexit_called == 2, "got %d\n", g_onexit_called);
}
static void init(void)
{
HMODULE module = LoadLibraryA("ucrtbase.dll");
p_initialize_onexit_table = (void*)GetProcAddress(module, "_initialize_onexit_table");
p_register_onexit_function = (void*)GetProcAddress(module, "_register_onexit_function");
p_execute_onexit_table = (void*)GetProcAddress(module, "_execute_onexit_table");
}
START_TEST(misc)
@ -153,4 +226,5 @@ START_TEST(misc)
test__initialize_onexit_table();
test__register_onexit_function();
test__execute_onexit_table();
}

View file

@ -279,7 +279,7 @@
@ varargs _execle(str str)
@ varargs _execlp(str str)
@ varargs _execlpe(str str)
@ stub _execute_onexit_table
@ cdecl _execute_onexit_table(ptr) MSVCRT__execute_onexit_table
@ cdecl _execv(str ptr)
@ cdecl _execve(str ptr ptr) MSVCRT__execve
@ cdecl _execvp(str ptr)