msvcrt: Protect onexit table with critical section.

Signed-off-by: Daniel Lehman <dlehman@esri.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Daniel Lehman 2017-08-31 14:59:12 -07:00 committed by Alexandre Julliard
parent b8d0a59a2e
commit 67012e8300
1 changed files with 26 additions and 4 deletions

View File

@ -41,6 +41,15 @@ typedef struct MSVCRT__onexit_table_t
MSVCRT__onexit_t *_end;
} MSVCRT__onexit_table_t;
static CRITICAL_SECTION MSVCRT_onexit_cs;
static CRITICAL_SECTION_DEBUG MSVCRT_onexit_cs_debug =
{
0, 0, &MSVCRT_onexit_cs,
{ &MSVCRT_onexit_cs_debug.ProcessLocksList, &MSVCRT_onexit_cs_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": MSVCRT_onexit_cs") }
};
static CRITICAL_SECTION MSVCRT_onexit_cs = { &MSVCRT_onexit_cs_debug, -1, 0, 0, 0, 0 };
extern int MSVCRT_app_type;
extern MSVCRT_wchar_t *MSVCRT__wpgmptr;
@ -368,12 +377,14 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
if (!table)
return -1;
EnterCriticalSection(&MSVCRT_onexit_cs);
if (!table->_first)
{
table->_first = MSVCRT_calloc(32, sizeof(void *));
if (!table->_first)
{
WARN("failed to allocate initial table.\n");
LeaveCriticalSection(&MSVCRT_onexit_cs);
return -1;
}
table->_last = table->_first;
@ -388,6 +399,7 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
if (!tmp)
{
WARN("failed to grow table.\n");
LeaveCriticalSection(&MSVCRT_onexit_cs);
return -1;
}
table->_first = tmp;
@ -397,6 +409,7 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
*table->_last = func;
table->_last++;
LeaveCriticalSection(&MSVCRT_onexit_cs);
return 0;
}
@ -406,24 +419,33 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
int CDECL MSVCRT__execute_onexit_table(MSVCRT__onexit_table_t *table)
{
MSVCRT__onexit_t *func;
MSVCRT__onexit_table_t copy;
TRACE("(%p)\n", table);
if (!table)
return -1;
EnterCriticalSection(&MSVCRT_onexit_cs);
if (!table->_first || table->_first >= table->_last)
{
LeaveCriticalSection(&MSVCRT_onexit_cs);
return 0;
}
copy._first = table->_first;
copy._last = table->_last;
copy._end = table->_end;
memset(table, 0, sizeof(*table));
MSVCRT__initialize_onexit_table(table);
LeaveCriticalSection(&MSVCRT_onexit_cs);
for (func = table->_last - 1; func >= table->_first; func--)
for (func = copy._last - 1; func >= copy._first; func--)
{
if (*func)
(*func)();
}
MSVCRT_free(table->_first);
memset(table, 0, sizeof(*table));
MSVCRT__initialize_onexit_table(table);
MSVCRT_free(copy._first);
return 0;
}