- Cleaned up the message queue when a thread exit (but not the process).
- Modified QUEUE_DeleteMsgQueue to exit gracefully (without crashing Wine) if queue link list is corrupted.
This commit is contained in:
parent
4d713f97e0
commit
91bb1f974c
|
@ -31,6 +31,7 @@ extern WORD USER_HeapSel;
|
|||
|
||||
void WINAPI USER_SignalProc(HANDLE16, UINT16, UINT16, HINSTANCE16, HQUEUE16);
|
||||
void USER_ExitWindows(void);
|
||||
void USER_QueueCleanup( HQUEUE16 hQueue );
|
||||
HGLOBAL16 USER_CallDefaultRsrcHandler( HGLOBAL16 hMemObj, HMODULE16 hModule,
|
||||
HRSRC16 hRsrc );
|
||||
|
||||
|
|
|
@ -335,6 +335,10 @@ void WINAPI ExitThread(
|
|||
SYSTEM_LOCK();
|
||||
thdb->exit_code = code;
|
||||
|
||||
/* cleanup the message queue, if there's one */
|
||||
if (thdb->teb.queue)
|
||||
USER_QueueCleanup( thdb->teb.queue );
|
||||
|
||||
/* FIXME: should free the stack somehow */
|
||||
#if 0
|
||||
/* FIXME: We cannot do this; once the current thread is destroyed,
|
||||
|
|
|
@ -512,9 +512,18 @@ BOOL32 QUEUE_DeleteMsgQueue( HQUEUE16 hQueue )
|
|||
while (*pPrev && (*pPrev != hQueue))
|
||||
{
|
||||
MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock16(*pPrev);
|
||||
|
||||
/* sanity check */
|
||||
if ( !msgQ || (msgQ->magic != QUEUE_MAGIC) )
|
||||
{
|
||||
/* HQUEUE link list is corrupted, try to exit gracefully */
|
||||
WARN( msg, "HQUEUE link list corrupted!\n");
|
||||
pPrev = 0;
|
||||
break;
|
||||
}
|
||||
pPrev = &msgQ->next;
|
||||
}
|
||||
if (*pPrev) *pPrev = msgQueue->next;
|
||||
if (pPrev && *pPrev) *pPrev = msgQueue->next;
|
||||
msgQueue->self = 0;
|
||||
|
||||
SYSTEM_UNLOCK();
|
||||
|
@ -579,7 +588,7 @@ static void QUEUE_Wait( DWORD wait_mask )
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_SetWakeBit `
|
||||
* QUEUE_SetWakeBit
|
||||
*
|
||||
* See "Windows Internals", p.449
|
||||
*/
|
||||
|
|
|
@ -161,22 +161,14 @@ static void USER_ModuleUnload( HMODULE16 hModule )
|
|||
}
|
||||
|
||||
/**********************************************************************
|
||||
* USER_AppExit
|
||||
* USER_QueueCleanup
|
||||
*/
|
||||
static void USER_AppExit( HTASK16 hTask, HINSTANCE16 hInstance, HQUEUE16 hQueue )
|
||||
void USER_QueueCleanup( HQUEUE16 hQueue )
|
||||
{
|
||||
if ( hQueue )
|
||||
{
|
||||
/* FIXME: empty clipboard if needed, maybe destroy menus (Windows
|
||||
* only complains about them but does nothing);
|
||||
*/
|
||||
|
||||
WND* desktop = WIN_GetDesktop();
|
||||
|
||||
/* Patch desktop window */
|
||||
if( desktop->hmemTaskQ == hQueue )
|
||||
desktop->hmemTaskQ = GetTaskQueue(TASK_GetNextTask(hTask));
|
||||
|
||||
/* Patch resident popup menu window */
|
||||
MENU_PatchResidentPopup( hQueue, NULL );
|
||||
|
||||
|
@ -193,6 +185,24 @@ static void USER_AppExit( HTASK16 hTask, HINSTANCE16 hInstance, HQUEUE16 hQueue
|
|||
/* Free the message queue */
|
||||
QUEUE_DeleteMsgQueue( hQueue );
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* USER_AppExit
|
||||
*/
|
||||
static void USER_AppExit( HTASK16 hTask, HINSTANCE16 hInstance, HQUEUE16 hQueue )
|
||||
{
|
||||
/* FIXME: empty clipboard if needed, maybe destroy menus (Windows
|
||||
* only complains about them but does nothing);
|
||||
*/
|
||||
|
||||
WND* desktop = WIN_GetDesktop();
|
||||
|
||||
/* Patch desktop window */
|
||||
if( desktop->hmemTaskQ == hQueue )
|
||||
desktop->hmemTaskQ = GetTaskQueue(TASK_GetNextTask(hTask));
|
||||
|
||||
USER_QueueCleanup(hQueue);
|
||||
|
||||
/* ModuleUnload() in "Internals" */
|
||||
|
||||
|
|
Loading…
Reference in New Issue