[PATCH 3/3] msvcrt: Implement quick_exit and _crt_at_quick_exit
Fabian Maurer
dark.shadow4 at web.de
Tue Jun 5 15:42:54 CDT 2018
Code taken from onexit logic and adapted-
Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
dlls/msvcrt/exit.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c
index 313a06ecd0..070a6753e8 100644
--- a/dlls/msvcrt/exit.c
+++ b/dlls/msvcrt/exit.c
@@ -30,8 +30,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
#define UNLOCK_EXIT _munlock(_EXIT_LOCK1)
static MSVCRT__onexit_t *MSVCRT_atexit_table = NULL;
+static MSVCRT__onexit_t *MSVCRT_atquickexit_table = NULL;
static int MSVCRT_atexit_table_size = 0;
+static int MSVCRT_atquickexit_table_size = 0;
static int MSVCRT_atexit_registered = 0; /* Points to free slot */
+static int MSVCRT_atquickexit_registered = 0; /* Points to free slot */
static MSVCRT_purecall_handler purecall_handler = NULL;
typedef struct MSVCRT__onexit_table_t
@@ -78,6 +81,22 @@ static void __MSVCRT__call_atexit(void)
}
}
+/* INTERNAL: call atexit functions */
+static void __MSVCRT__call_atquickexit(void)
+{
+ TRACE("%d atquickexit functions to call\n", MSVCRT_atquickexit_registered);
+
+ /* Last registered gets executed first */
+ while (MSVCRT_atquickexit_registered > 0)
+ {
+ MSVCRT_atquickexit_registered--;
+ TRACE("next is %p\n",MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered]);
+ if (MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered])
+ (*MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered])();
+ TRACE("returned\n");
+ }
+}
+
/*********************************************************************
* __dllonexit (MSVCRT.@)
*/
@@ -125,7 +144,8 @@ void CDECL MSVCRT__exit(int exitcode)
*/
void CDECL MSVCRT_quick_exit(int exitcode)
{
- FIXME("partial stub: (%d)\n", exitcode);
+ TRACE("(%d)\n", exitcode);
+ __MSVCRT__call_atquickexit();
MSVCRT__exit(exitcode);
}
@@ -363,7 +383,31 @@ int CDECL MSVCRT_atexit(void (*func)(void))
*/
int CDECL MSVCRT__crt_at_quick_exit(void (*func)(void))
{
- FIXME("stub: (%p)\n", func);
+ TRACE("(%p)\n",func);
+
+ if (!func)
+ return -1;
+
+ LOCK_EXIT;
+ if (MSVCRT_atquickexit_registered > MSVCRT_atquickexit_table_size - 1)
+ {
+ MSVCRT__onexit_t *newtable;
+ TRACE("expanding table\n");
+ newtable = MSVCRT_calloc(MSVCRT_atquickexit_table_size + 32, sizeof(void *));
+ if (!newtable)
+ {
+ TRACE("failed!\n");
+ UNLOCK_EXIT;
+ return -1;
+ }
+ memcpy (newtable, MSVCRT_atquickexit_table, MSVCRT_atquickexit_table_size*sizeof(void *));
+ MSVCRT_atquickexit_table_size += 32;
+ MSVCRT_free (MSVCRT_atquickexit_table);
+ MSVCRT_atquickexit_table = newtable;
+ }
+ MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered] = (MSVCRT__onexit_t)func;
+ MSVCRT_atquickexit_registered++;
+ UNLOCK_EXIT;
return 0;
}
--
2.17.1
More information about the wine-devel
mailing list