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:
parent
b8d0a59a2e
commit
67012e8300
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue