Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
93b23d74
Commit
93b23d74
authored
Mar 22, 1999
by
Ulrich Weigand
Committed by
Alexandre Julliard
Mar 22, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Run Win32 processes in their own threads.
Process exit sequence adapted.
parent
f016752b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
118 additions
and
115 deletions
+118
-115
task.h
include/task.h
+1
-0
task.c
loader/task.c
+103
-90
process.c
scheduler/process.c
+12
-17
thread.c
scheduler/thread.c
+2
-8
No files found.
include/task.h
View file @
93b23d74
...
...
@@ -150,6 +150,7 @@ extern BOOL TASK_Create( struct _THDB *thdb, struct _NE_MODULE *pModule,
HINSTANCE16
hInstance
,
HINSTANCE16
hPrevInstance
,
UINT16
cmdShow
);
extern
void
TASK_StartTask
(
HTASK16
hTask
);
extern
void
TASK_KillTask
(
HTASK16
hTask
);
extern
void
TASK_KillCurrentTask
(
INT16
exitCode
);
extern
HTASK16
TASK_GetNextTask
(
HTASK16
hTask
);
extern
BOOL
TASK_Reschedule
(
void
);
...
...
loader/task.c
View file @
93b23d74
...
...
@@ -57,7 +57,7 @@ THHOOK *pThhook = &DefaultThhook;
static
HTASK16
hTaskToKill
=
0
;
static
UINT16
nTaskCount
=
0
;
static
void
TASK_YieldToSystem
(
TDB
*
);
static
void
TASK_YieldToSystem
(
void
);
extern
BOOL
THREAD_InitDone
;
...
...
@@ -240,48 +240,8 @@ static void TASK_CallToStart(void)
if
(
pModule
->
flags
&
NE_FFLAGS_WIN32
)
{
/* FIXME: all this is an ugly hack */
OFSTRUCT
*
ofs
=
(
OFSTRUCT
*
)((
char
*
)(
pModule
)
+
(
pModule
)
->
fileinfo
);
LPTHREAD_START_ROUTINE
entry
=
(
LPTHREAD_START_ROUTINE
)
RVA_PTR
(
pModule
->
module32
,
OptionalHeader
.
AddressOfEntryPoint
);
/* Create 32-bit MODREF */
if
(
!
PE_CreateModule
(
pModule
->
module32
,
ofs
,
0
,
FALSE
)
)
{
ERR
(
task
,
"Could not initialize process
\n
"
);
ExitProcess
(
1
);
}
/* Initialize Thread-Local Storage */
PE_InitTls
(
pTask
->
thdb
);
if
(
PE_HEADER
(
pModule
->
module32
)
->
OptionalHeader
.
Subsystem
==
IMAGE_SUBSYSTEM_WINDOWS_CUI
)
AllocConsole
();
MODULE_InitializeDLLs
(
0
,
DLL_PROCESS_ATTACH
,
(
LPVOID
)
-
1
);
TRACE
(
relay
,
"(entryproc=%p)
\n
"
,
entry
);
#if 1
ExitProcess
(
entry
(
NULL
)
);
#else
{
DWORD
size
=
PE_HEADER
(
pModule
->
module32
)
->
OptionalHeader
.
SizeOfStackReserve
;
DWORD
id
;
THDB
*
thdb
;
CreateThread
(
NULL
,
size
,
entry
,
NULL
,
0
,
&
id
);
thdb
=
THREAD_IdToTHDB
(
id
);
while
(
thdb
->
exit_code
==
0x103
)
{
WaitEvent16
(
0
);
QUEUE_Signal
(
pTask
->
hSelf
);
}
ExitProcess
(
thdb
->
exit_code
);
}
#endif
ERR
(
task
,
"Called for Win32 task!
\n
"
);
ExitProcess
(
1
);
}
else
if
(
pModule
->
dos_image
)
{
...
...
@@ -356,7 +316,7 @@ BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
/* Fill the task structure */
pTask
->
nEvents
=
1
;
/* So the task can be started */
pTask
->
nEvents
=
0
;
pTask
->
hSelf
=
hTask
;
pTask
->
flags
=
0
;
...
...
@@ -498,6 +458,9 @@ BOOL TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance,
*/
void
TASK_StartTask
(
HTASK16
hTask
)
{
TDB
*
pTask
=
(
TDB
*
)
GlobalLock16
(
hTask
);
if
(
!
pTask
)
return
;
/* Add the task to the linked list */
SYSLEVEL_EnterWin16Lock
();
...
...
@@ -511,15 +474,26 @@ void TASK_StartTask( HTASK16 hTask )
if
(
TASK_AddTaskEntryBreakpoint
)
TASK_AddTaskEntryBreakpoint
(
hTask
);
/* Get the task up and running. If we ourselves are a 16-bit task,
we simply Yield(). If we are 32-bit however, we need to signal
the main process somehow (NOT YET IMPLEMENTED!) */
/* Get the task up and running. */
if
(
THREAD_IsWin16
(
pTask
->
thdb
)
)
{
pTask
->
nEvents
++
;
/* If we ourselves are a 16-bit task, we simply Yield().
If we are 32-bit however, we need to signal the scheduler. */
if
(
THREAD_IsWin16
(
THREAD_Current
()
)
)
OldYield16
();
if
(
THREAD_IsWin16
(
THREAD_Current
()
)
)
OldYield16
();
else
EVENT_WakeUp
();
}
else
/* wake-up the scheduler waiting in EVENT_WaitNetEvent */
EVENT_WakeUp
();
{
/* To start a 32-bit task, we spawn its initial thread. */
SYSDEPS_SpawnThread
(
pTask
->
thdb
);
}
}
...
...
@@ -560,37 +534,25 @@ static void TASK_DeleteTask( HTASK16 hTask )
GlobalFreeAll16
(
hPDB
);
}
/***********************************************************************
* TASK_KillCurrentTask
*
* Kill the currently running task. As it's not possible to kill the
* current task like this, it is simply marked for destruction, and will
* be killed when either TASK_Reschedule or this function is called again
* in the context of another task.
* TASK_KillTask
*/
void
TASK_Kill
CurrentTask
(
INT16
exitCode
)
void
TASK_Kill
Task
(
HTASK16
hTask
)
{
TDB
*
pTask
=
(
TDB
*
)
GlobalLock16
(
GetCurrentTask
()
);
NE_MODULE
*
pModule
=
NE_GetPtr
(
pTask
->
hModule
);
if
(
!
pTask
)
USER_ExitWindows
();
/* No current task yet */
TDB
*
pTask
;
if
(
!
THREAD_IsWin16
(
THREAD_Current
()
)
)
/* Enter the Win16Lock to protect global data structures */
SYSLEVEL_EnterWin16Lock
();
if
(
!
hTask
)
hTask
=
GetCurrentTask
();
pTask
=
(
TDB
*
)
GlobalLock16
(
hTask
);
if
(
!
pTask
)
{
FIXME
(
task
,
"called for Win32 thread (%04x)!
\n
"
,
THREAD_Current
()
->
teb_sel
);
SYSLEVEL_LeaveWin16Lock
(
);
return
;
}
/* Enter the Win16Lock to protect global data structures
NOTE: We never explicitly leave it again. This shouldn't matter
though, as it will be released in TASK_Reschedule and this
task won't ever get scheduled again ... */
SYSLEVEL_EnterWin16Lock
();
assert
(
hCurrentTask
==
GetCurrentTask
());
TRACE
(
task
,
"Killing task %04x
\n
"
,
hCurrentTask
);
TRACE
(
task
,
"Killing task %04x
\n
"
,
hTask
);
/* Delete active sockets */
...
...
@@ -598,9 +560,12 @@ void TASK_KillCurrentTask( INT16 exitCode )
WINSOCK_DeleteTaskWSI
(
pTask
,
pTask
->
pwsi
);
#ifdef MZ_SUPPORTED
{
/* Kill DOS VM task */
NE_MODULE
*
pModule
=
NE_GetPtr
(
pTask
->
hModule
);
if
(
pModule
->
lpDosTask
)
MZ_KillModule
(
pModule
->
lpDosTask
);
}
#endif
/* Perform USER cleanup */
...
...
@@ -609,13 +574,6 @@ void TASK_KillCurrentTask( INT16 exitCode )
pTask
->
userhandler
(
hCurrentTask
,
USIG_TERMINATION
,
0
,
pTask
->
hInstance
,
pTask
->
hQueue
);
if
(
hTaskToKill
&&
(
hTaskToKill
!=
hCurrentTask
))
{
/* If another task is already marked for destruction, */
/* we can kill it now, as we are in another context. */
TASK_DeleteTask
(
hTaskToKill
);
}
if
(
nTaskCount
<=
1
)
{
TRACE
(
task
,
"this is the last task, exiting
\n
"
);
...
...
@@ -631,22 +589,71 @@ void TASK_KillCurrentTask( INT16 exitCode )
Callout
.
PostAppMessage16
(
PROCESS_Initial
()
->
task
,
WM_NULL
,
0
,
0
);
/* Remove the task from the list to be sure we never switch back to it */
TASK_UnlinkTask
(
h
Current
Task
);
TASK_UnlinkTask
(
hTask
);
if
(
nTaskCount
)
{
TDB
*
p
=
(
TDB
*
)
GlobalLock16
(
hFirstTask
);
while
(
p
)
{
if
(
p
->
hYieldTo
==
h
Current
Task
)
p
->
hYieldTo
=
0
;
if
(
p
->
hYieldTo
==
hTask
)
p
->
hYieldTo
=
0
;
p
=
(
TDB
*
)
GlobalLock16
(
p
->
hNext
);
}
}
hTaskToKill
=
hCurrentTask
;
hLockedTask
=
0
;
pTask
->
nEvents
=
0
;
TASK_YieldToSystem
(
pTask
);
if
(
hLockedTask
==
hTask
)
hLockedTask
=
0
;
if
(
hTaskToKill
&&
(
hTaskToKill
!=
hCurrentTask
)
)
{
/* If another task is already marked for destruction, */
/* we can kill it now, as we are in another context. */
TASK_DeleteTask
(
hTaskToKill
);
hTaskToKill
=
0
;
}
/*
* If hTask is not the task currently scheduled by the Win16
* scheduler, we simply delete it; otherwise we mark it for
* destruction. Note that if the current task is a 32-bit
* one, hCurrentTask is *different* from GetCurrentTask()!
*/
if
(
hTask
==
hCurrentTask
)
{
assert
(
hTaskToKill
==
0
||
hTaskToKill
==
hCurrentTask
);
hTaskToKill
=
hCurrentTask
;
}
else
TASK_DeleteTask
(
hTask
);
SYSLEVEL_LeaveWin16Lock
();
}
/***********************************************************************
* TASK_KillCurrentTask
*
* Kill the currently running task. As it's not possible to kill the
* current task like this, it is simply marked for destruction, and will
* be killed when either TASK_Reschedule or this function is called again
* in the context of another task.
*/
void
TASK_KillCurrentTask
(
INT16
exitCode
)
{
if
(
!
THREAD_IsWin16
(
THREAD_Current
()
)
)
{
FIXME
(
task
,
"called for Win32 thread (%04x)!
\n
"
,
THREAD_Current
()
->
teb_sel
);
return
;
}
assert
(
hCurrentTask
==
GetCurrentTask
());
TRACE
(
task
,
"Killing current task %04x
\n
"
,
hCurrentTask
);
TASK_KillTask
(
0
);
TASK_YieldToSystem
();
/* We should never return from this Yield() */
...
...
@@ -824,7 +831,7 @@ BOOL TASK_Reschedule(void)
* Scheduler interface, this way we ensure that all "unsafe" events are
* processed outside the scheduler.
*/
void
TASK_YieldToSystem
(
TDB
*
pTask
)
static
void
TASK_YieldToSystem
(
void
)
{
if
(
!
THREAD_IsWin16
(
THREAD_Current
()
)
)
{
...
...
@@ -944,7 +951,7 @@ BOOL16 WINAPI WaitEvent16( HTASK16 hTask )
pTask
->
nEvents
--
;
return
FALSE
;
}
TASK_YieldToSystem
(
pTask
);
TASK_YieldToSystem
();
/* When we get back here, we have an event */
...
...
@@ -963,6 +970,12 @@ void WINAPI PostEvent16( HTASK16 hTask )
if
(
!
hTask
)
hTask
=
GetCurrentTask
();
if
(
!
(
pTask
=
(
TDB
*
)
GlobalLock16
(
hTask
)))
return
;
if
(
!
THREAD_IsWin16
(
pTask
->
thdb
)
)
{
FIXME
(
task
,
"called for Win32 thread (%04x)!
\n
"
,
pTask
->
thdb
->
teb_sel
);
return
;
}
pTask
->
nEvents
++
;
if
(
!
THREAD_IsWin16
(
THREAD_Current
()
)
)
...
...
@@ -1028,7 +1041,7 @@ void WINAPI OldYield16(void)
}
if
(
pCurTask
)
pCurTask
->
nEvents
++
;
/* Make sure we get back here */
TASK_YieldToSystem
(
pCurTask
);
TASK_YieldToSystem
();
if
(
pCurTask
)
pCurTask
->
nEvents
--
;
}
...
...
scheduler/process.c
View file @
93b23d74
...
...
@@ -288,6 +288,7 @@ BOOL PROCESS_Init(void)
initial_pdb
.
ring0_threads
=
1
;
initial_pdb
.
group
=
&
initial_pdb
;
initial_pdb
.
priority
=
8
;
/* Normal */
initial_pdb
.
flags
=
PDB32_WIN16_PROC
;
/* Initialize virtual memory management */
if
(
!
VIRTUAL_Init
())
return
FALSE
;
...
...
@@ -330,8 +331,11 @@ void PROCESS_Start(void)
LPTHREAD_START_ROUTINE
entry
;
THDB
*
thdb
=
THREAD_Current
();
PDB
*
pdb
=
thdb
->
process
;
NE_MODULE
*
pModule
=
(
NE_MODULE
*
)
thdb
->
entry_arg
;
/* hack */
TDB
*
pTask
=
(
TDB
*
)
GlobalLock16
(
pdb
->
task
);
NE_MODULE
*
pModule
=
NE_GetPtr
(
pTask
->
hModule
);
OFSTRUCT
*
ofs
=
(
OFSTRUCT
*
)((
char
*
)(
pModule
)
+
(
pModule
)
->
fileinfo
);
#if 0
/* Initialize the critical section */
InitializeCriticalSection( &pdb->crit_section );
...
...
@@ -347,10 +351,10 @@ void PROCESS_Start(void)
if (!PROCESS_CreateEnvDB()) goto error;
#if 0
if (pdb->env_db->startup_info->dwFlags & STARTF_USESHOWWINDOW)
cmdShow = pdb->env_db->startup_info->wShowWindow;
if (!TASK_Create( thdb, pModule, 0, 0, cmdShow )) goto error;
#endif
/* Map system DLLs into this process (from initial process) */
...
...
@@ -358,10 +362,7 @@ void PROCESS_Start(void)
pdb
->
modref_list
=
PROCESS_Initial
()
->
modref_list
;
/* Create 32-bit MODREF */
{
OFSTRUCT
*
ofs
=
(
OFSTRUCT
*
)((
char
*
)(
pModule
)
+
(
pModule
)
->
fileinfo
);
if
(
!
PE_CreateModule
(
pModule
->
module32
,
ofs
,
0
,
FALSE
))
goto
error
;
}
if
(
!
PE_CreateModule
(
pModule
->
module32
,
ofs
,
0
,
FALSE
))
goto
error
;
/* Initialize thread-local storage */
...
...
@@ -463,6 +464,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
goto
error
;
info
->
hThread
=
server_thandle
;
info
->
dwThreadId
=
(
DWORD
)
thdb
->
server_tid
;
thdb
->
startup
=
PROCESS_Start
;
/* Duplicate the standard handles */
...
...
@@ -509,20 +511,13 @@ error:
*/
void
WINAPI
ExitProcess
(
DWORD
status
)
{
PDB
*
pdb
=
PROCESS_Current
();
TDB
*
pTask
=
(
TDB
*
)
GlobalLock16
(
pdb
->
task
);
if
(
pTask
)
pTask
->
nEvents
++
;
MODULE_InitializeDLLs
(
0
,
DLL_PROCESS_DETACH
,
NULL
);
if
(
pTask
&&
pTask
->
thdb
!=
THREAD_Current
()
)
TerminateProcess
(
GetCurrentProcess
(),
status
);
/* FIXME: should kill all running threads of this process */
pdb
->
exit_code
=
status
;
if
(
THREAD_IsWin16
(
THREAD_Current
()
)
)
TASK_KillCurrentTask
(
status
);
__RESTORE_ES
;
/* Necessary for Pietrek's showseh example program */
T
ASK_KillCurrentTask
(
status
);
TASK_KillTask
(
0
);
T
erminateProcess
(
GetCurrentProcess
(),
status
);
}
...
...
scheduler/thread.c
View file @
93b23d74
...
...
@@ -54,13 +54,7 @@ THDB *THREAD_Current(void)
*/
BOOL
THREAD_IsWin16
(
THDB
*
thdb
)
{
if
(
!
thdb
||
!
thdb
->
process
)
return
TRUE
;
else
{
TDB
*
pTask
=
(
TDB
*
)
GlobalLock16
(
thdb
->
process
->
task
);
return
!
pTask
||
pTask
->
thdb
==
thdb
;
}
return
!
thdb
||
!
(
thdb
->
teb
.
flags
&
TEBF_WIN32
);
}
/***********************************************************************
...
...
@@ -188,7 +182,7 @@ THDB *THREAD_CreateInitialThread( PDB *pdb, int server_fd )
initial_thdb
.
process
=
pdb
;
initial_thdb
.
teb
.
except
=
(
void
*
)
-
1
;
initial_thdb
.
teb
.
self
=
&
initial_thdb
.
teb
;
initial_thdb
.
teb
.
flags
=
TEBF_WIN32
;
initial_thdb
.
teb
.
flags
=
/* TEBF_WIN32 */
0
;
initial_thdb
.
teb
.
tls_ptr
=
initial_thdb
.
tls_array
;
initial_thdb
.
teb
.
process
=
pdb
;
initial_thdb
.
exit_code
=
0x103
;
/* STILL_ACTIVE */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment