Nikolay Sivov : ucrtbase: Implement _execute_onexit_table().

Alexandre Julliard julliard at wine.codeweavers.com
Wed Apr 27 10:45:43 CDT 2016


Module: wine
Branch: master
Commit: f3465ecbae0b7f99008c4ad63680b7315a247eec
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f3465ecbae0b7f99008c4ad63680b7315a247eec

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Apr 27 09:21:12 2016 +0300

ucrtbase: Implement _execute_onexit_table().

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 .../api-ms-win-crt-runtime-l1-1-0.spec             |  2 +-
 dlls/msvcrt/exit.c                                 | 27 ++++++++
 dlls/ucrtbase/tests/misc.c                         | 74 ++++++++++++++++++++++
 dlls/ucrtbase/ucrtbase.spec                        |  2 +-
 4 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec
index ceb4e35..e138bf6 100644
--- a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec
@@ -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
diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c
index 60aa85d..9ba0891 100644
--- a/dlls/msvcrt/exit.c
+++ b/dlls/msvcrt/exit.c
@@ -400,6 +400,33 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
 }
 
 /*********************************************************************
+ *		_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.@)
  */
 MSVCRT_purecall_handler CDECL _set_purecall_handler(MSVCRT_purecall_handler function)
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 0b77066..63ea465 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -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();
 }
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index 3ac30eb..cfb2a0a 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -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)




More information about the wine-cvs mailing list