Check all Callouts function pointers for NULL before using them.
Don't load USER dll if not needed by the application.
diff --git a/loader/task.c b/loader/task.c
index 4db25a2..e6bafa0 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -379,78 +379,62 @@
/***********************************************************************
* TASK_KillTask
*/
-void TASK_KillTask( HTASK16 hTask )
+void TASK_ExitTask(void)
{
TDB *pTask;
+ DWORD lockCount;
/* Enter the Win16Lock to protect global data structures */
SYSLEVEL_EnterWin16Lock();
- if ( !hTask ) hTask = GetCurrentTask();
- pTask = (TDB *)GlobalLock16( hTask );
+ pTask = (TDB *)GlobalLock16( GetCurrentTask() );
if ( !pTask )
{
SYSLEVEL_LeaveWin16Lock();
return;
}
- TRACE("Killing task %04x\n", hTask );
+ TRACE("Killing task %04x\n", pTask->hSelf );
/* Perform USER cleanup */
- TASK_CallTaskSignalProc( USIG16_TERMINATION, hTask );
+ TASK_CallTaskSignalProc( USIG16_TERMINATION, pTask->hSelf );
PROCESS_CallUserSignalProc( USIG_PROCESS_EXIT, 0 );
PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );
PROCESS_CallUserSignalProc( USIG_PROCESS_DESTROY, 0 );
- if (nTaskCount <= 1)
+ /* Remove the task from the list to be sure we never switch back to it */
+ TASK_UnlinkTask( pTask->hSelf );
+
+ if (!nTaskCount || (nTaskCount == 1 && hFirstTask == initial_task))
{
TRACE("this is the last task, exiting\n" );
+ ERR("done\n");
ExitKernel16();
}
- /* FIXME: Hack! Send a message to the initial task so that
- * the GetMessage wakes up and the initial task can check whether
- * it is the only remaining one and terminate itself ...
- * The initial task should probably install hooks or something
- * to get informed about task termination :-/
- */
- Callout.PostAppMessage16( initial_task, WM_NULL, 0, 0 );
-
- /* Remove the task from the list to be sure we never switch back to it */
- TASK_UnlinkTask( hTask );
if( nTaskCount )
{
TDB* p = (TDB *)GlobalLock16( hFirstTask );
while( p )
{
- if( p->hYieldTo == hTask ) p->hYieldTo = 0;
+ if( p->hYieldTo == pTask->hSelf ) p->hYieldTo = 0;
p = (TDB *)GlobalLock16( p->hNext );
}
}
pTask->nEvents = 0;
- if ( hLockedTask == hTask )
+ if ( hLockedTask == pTask->hSelf )
hLockedTask = 0;
- TASK_DeleteTask( hTask );
+ TASK_DeleteTask( pTask->hSelf );
- /* When deleting the current task ... */
- if ( hTask == hCurrentTask )
- {
- DWORD lockCount;
+ /* ... schedule another one ... */
+ TASK_Reschedule();
- /* ... schedule another one ... */
- TASK_Reschedule();
-
- /* ... and completely release the Win16Lock, just in case. */
- ReleaseThunkLock( &lockCount );
-
- return;
- }
-
- SYSLEVEL_LeaveWin16Lock();
+ /* ... and completely release the Win16Lock, just in case. */
+ ReleaseThunkLock( &lockCount );
}
/***********************************************************************
@@ -838,7 +822,7 @@
TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
if (pCurTask) pCurTask->hYieldTo = 0;
- if (pCurTask && pCurTask->hQueue) Callout.UserYield16();
+ if (pCurTask && pCurTask->hQueue && Callout.UserYield16) Callout.UserYield16();
else OldYield16();
}
@@ -1148,7 +1132,7 @@
TEB *teb = NtCurrentTeb();
if (!teb) return 0;
- if (!teb->queue)
+ if (!teb->queue && Callout.InitThreadInput16)
Callout.InitThreadInput16( 0, THREAD_IsWin16(teb)? 4 : 5 );
if (!teb->queue)