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
12f29b50
Commit
12f29b50
authored
Mar 17, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Have threads and processes exit more cleanly whenever possible.
parent
aabef029
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
160 additions
and
96 deletions
+160
-96
server.h
include/server.h
+5
-2
thread.h
include/thread.h
+1
-1
winbase.h
include/winbase.h
+2
-2
windef.h
include/windef.h
+6
-4
module.c
loader/module.c
+4
-3
client.c
scheduler/client.c
+12
-19
process.c
scheduler/process.c
+11
-5
sysdeps.c
scheduler/sysdeps.c
+16
-17
thread.c
scheduler/thread.c
+24
-3
process.c
server/process.c
+12
-5
process.h
server/process.h
+0
-1
ptrace.c
server/ptrace.c
+4
-4
request.c
server/request.c
+26
-12
request.h
server/request.h
+0
-5
thread.c
server/thread.c
+22
-9
thread.h
server/thread.h
+2
-2
trace.c
server/trace.c
+13
-2
No files found.
include/server.h
View file @
12f29b50
...
...
@@ -191,6 +191,7 @@ struct terminate_process_request
{
IN
int
handle
;
/* process handle to terminate */
IN
int
exit_code
;
/* process exit code */
OUT
int
self
;
/* suicide? */
};
...
...
@@ -199,6 +200,8 @@ struct terminate_thread_request
{
IN
int
handle
;
/* thread handle to terminate */
IN
int
exit_code
;
/* thread exit code */
OUT
int
self
;
/* suicide? */
OUT
int
last
;
/* last thread in this process? */
};
...
...
@@ -1202,7 +1205,7 @@ enum request
REQ_NB_REQUESTS
};
#define SERVER_PROTOCOL_VERSION
3
#define SERVER_PROTOCOL_VERSION
4
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
...
...
@@ -1219,7 +1222,7 @@ enum request
extern
unsigned
int
server_call_noerr
(
enum
request
req
);
extern
unsigned
int
server_call_fd
(
enum
request
req
,
int
fd_out
,
int
*
fd_in
);
extern
void
server_protocol_error
(
const
char
*
err
,
...
);
extern
void
server_protocol_error
(
const
char
*
err
,
...
)
WINE_NORETURN
;
/* get a pointer to the request buffer */
static
inline
void
*
WINE_UNUSED
get_req_buffer
(
void
)
...
...
include/thread.h
View file @
12f29b50
...
...
@@ -131,6 +131,6 @@ extern TEB *THREAD_IdToTEB( DWORD id );
/* scheduler/sysdeps.c */
extern
int
SYSDEPS_SpawnThread
(
TEB
*
teb
);
extern
void
SYSDEPS_SetCurThread
(
TEB
*
teb
);
extern
void
SYSDEPS_ExitThread
(
void
)
;
extern
void
SYSDEPS_ExitThread
(
int
status
)
WINE_NORETURN
;
#endif
/* __WINE_THREAD_H */
include/winbase.h
View file @
12f29b50
...
...
@@ -1223,8 +1223,8 @@ BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW lpTimeFmtEnumProc, LCID Loca
#define EnumTimeFormats WINELIB_NAME_AW(EnumTimeFormats)
BOOL
WINAPI
EqualSid
(
PSID
,
PSID
);
BOOL
WINAPI
EqualPrefixSid
(
PSID
,
PSID
);
VOID
WINAPI
ExitProcess
(
DWORD
);
VOID
WINAPI
ExitThread
(
DWORD
);
VOID
WINAPI
ExitProcess
(
DWORD
)
WINE_NORETURN
;
VOID
WINAPI
ExitThread
(
DWORD
)
WINE_NORETURN
;
DWORD
WINAPI
ExpandEnvironmentStringsA
(
LPCSTR
,
LPSTR
,
DWORD
);
DWORD
WINAPI
ExpandEnvironmentStringsW
(
LPCWSTR
,
LPWSTR
,
DWORD
);
#define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)
...
...
include/windef.h
View file @
12f29b50
...
...
@@ -353,11 +353,13 @@ typedef LRESULT (CALLBACK *WNDPROC)(HWND,UINT,WPARAM,LPARAM);
/* Macro for structure packing. */
#ifdef __GNUC__
#define WINE_PACKED __attribute__ ((packed))
#define WINE_UNUSED __attribute__ ((unused))
#define WINE_PACKED __attribute__((packed))
#define WINE_UNUSED __attribute__((unused))
#define WINE_NORETURN __attribute__((noreturn))
#else
#define WINE_PACKED
/* nothing */
#define WINE_UNUSED
/* nothing */
#define WINE_PACKED
/* nothing */
#define WINE_UNUSED
/* nothing */
#define WINE_NORETURN
/* nothing */
#endif
/* Macros to split words and longs. */
...
...
loader/module.c
View file @
12f29b50
...
...
@@ -221,14 +221,13 @@ BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
* Send DLL process detach notifications. See the comment about calling
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified.
*
* NOTE: Assumes that the process critical section is held!
*
*/
void
MODULE_DllProcessDetach
(
BOOL
bForceDetach
,
LPVOID
lpReserved
)
{
WINE_MODREF
*
wm
;
EnterCriticalSection
(
&
PROCESS_Current
()
->
crit_section
);
do
{
for
(
wm
=
PROCESS_Current
()
->
modref_list
;
wm
;
wm
=
wm
->
next
)
...
...
@@ -248,6 +247,8 @@ void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
break
;
}
}
while
(
wm
);
LeaveCriticalSection
(
&
PROCESS_Current
()
->
crit_section
);
}
/*************************************************************************
...
...
scheduler/client.c
View file @
12f29b50
...
...
@@ -78,17 +78,6 @@ static void fatal_perror( const char *err, ... )
}
/***********************************************************************
* CLIENT_Die
*
* Die on protocol errors or socket close
*/
static
void
CLIENT_Die
(
void
)
{
close
(
NtCurrentTeb
()
->
socket
);
SYSDEPS_ExitThread
();
}
/***********************************************************************
* server_protocol_error
*/
void
server_protocol_error
(
const
char
*
err
,
...
)
...
...
@@ -99,7 +88,7 @@ void server_protocol_error( const char *err, ... )
fprintf
(
stderr
,
"Client protocol error:%p: "
,
NtCurrentTeb
()
->
tid
);
vfprintf
(
stderr
,
err
,
args
);
va_end
(
args
);
CLIENT_Die
(
);
SYSDEPS_ExitThread
(
1
);
}
...
...
@@ -110,7 +99,7 @@ static void server_perror( const char *err )
{
fprintf
(
stderr
,
"Client protocol error:%p: "
,
NtCurrentTeb
()
->
tid
);
perror
(
err
);
CLIENT_Die
(
);
SYSDEPS_ExitThread
(
1
);
}
...
...
@@ -126,7 +115,7 @@ static void send_request( enum request req )
return
;
if
(
ret
==
-
1
)
{
if
(
errno
==
EPIPE
)
CLIENT_Die
(
);
if
(
errno
==
EPIPE
)
SYSDEPS_ExitThread
(
0
);
server_perror
(
"sendmsg"
);
}
server_protocol_error
(
"partial msg sent %d/%d
\n
"
,
ret
,
sizeof
(
req
)
);
...
...
@@ -170,7 +159,7 @@ static void send_request_fd( enum request req, int fd )
if
((
ret
=
sendmsg
(
NtCurrentTeb
()
->
socket
,
&
msghdr
,
0
))
==
sizeof
(
req
))
return
;
if
(
ret
==
-
1
)
{
if
(
errno
==
EPIPE
)
CLIENT_Die
(
);
if
(
errno
==
EPIPE
)
SYSDEPS_ExitThread
(
0
);
server_perror
(
"sendmsg"
);
}
server_protocol_error
(
"partial msg sent %d/%d
\n
"
,
ret
,
sizeof
(
req
)
);
...
...
@@ -190,15 +179,17 @@ static unsigned int wait_reply(void)
{
if
((
ret
=
read
(
NtCurrentTeb
()
->
socket
,
&
res
,
sizeof
(
res
)
))
==
sizeof
(
res
))
return
res
;
if
(
!
ret
)
break
;
if
(
ret
==
-
1
)
{
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EPIPE
)
CLIENT_Die
()
;
if
(
errno
==
EPIPE
)
break
;
server_perror
(
"read"
);
}
if
(
!
ret
)
CLIENT_Die
();
/* the server closed the connection; time to die... */
server_protocol_error
(
"partial msg received %d/%d
\n
"
,
ret
,
sizeof
(
res
)
);
}
/* the server closed the connection; time to die... */
SYSDEPS_ExitThread
(
0
);
}
...
...
@@ -248,15 +239,17 @@ static unsigned int wait_reply_fd( int *fd )
#endif
return
res
;
}
if
(
!
ret
)
break
;
if
(
ret
==
-
1
)
{
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EPIPE
)
CLIENT_Die
()
;
if
(
errno
==
EPIPE
)
break
;
server_perror
(
"recvmsg"
);
}
if
(
!
ret
)
CLIENT_Die
();
/* the server closed the connection; time to die... */
server_protocol_error
(
"partial seq received %d/%d
\n
"
,
ret
,
sizeof
(
res
)
);
}
/* the server closed the connection; time to die... */
SYSDEPS_ExitThread
(
0
);
}
...
...
scheduler/process.c
View file @
12f29b50
...
...
@@ -627,12 +627,16 @@ error:
*/
void
WINAPI
ExitProcess
(
DWORD
status
)
{
EnterCriticalSection
(
&
PROCESS_Current
()
->
crit_section
);
MODULE_DllProcessDetach
(
TRUE
,
(
LPVOID
)
1
);
LeaveCriticalSection
(
&
PROCESS_Current
()
->
crit_section
);
struct
terminate_process_request
*
req
=
get_req_buffer
();
MODULE_DllProcessDetach
(
TRUE
,
(
LPVOID
)
1
);
TASK_KillTask
(
0
);
TerminateProcess
(
GetCurrentProcess
(),
status
);
/* send the exit code to the server */
req
->
handle
=
GetCurrentProcess
();
req
->
exit_code
=
status
;
server_call
(
REQ_TERMINATE_PROCESS
);
exit
(
status
);
}
/***********************************************************************
...
...
@@ -649,10 +653,12 @@ void WINAPI ExitProcess16( WORD status )
*/
BOOL
WINAPI
TerminateProcess
(
HANDLE
handle
,
DWORD
exit_code
)
{
BOOL
ret
;
struct
terminate_process_request
*
req
=
get_req_buffer
();
req
->
handle
=
handle
;
req
->
exit_code
=
exit_code
;
return
!
server_call
(
REQ_TERMINATE_PROCESS
);
if
((
ret
=
!
server_call
(
REQ_TERMINATE_PROCESS
))
&&
req
->
self
)
exit
(
exit_code
);
return
ret
;
}
...
...
scheduler/sysdeps.c
View file @
12f29b50
...
...
@@ -137,7 +137,7 @@ static void SYSDEPS_StartThread( TEB *teb )
TerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
SYSDEPS_ExitThread
();
/* should never get here */
SYSDEPS_ExitThread
(
0
);
/* should never get here */
}
...
...
@@ -153,31 +153,31 @@ int SYSDEPS_SpawnThread( TEB *teb )
#ifdef linux
if
(
clone
(
(
int
(
*
)(
void
*
))
SYSDEPS_StartThread
,
teb
->
stack_top
,
CLONE_VM
|
CLONE_FS
|
CLONE_FILES
|
SIGCHLD
,
teb
)
<
0
)
CLONE_VM
|
CLONE_FS
|
SIGCHLD
,
teb
)
<
0
)
return
-
1
;
/* FIXME: close the child socket in the parent process */
/* close( thread->socket );*/
close
(
teb
->
socket
);
/* close the child socket in the parent */
return
0
;
#endif
#ifdef HAVE_RFORK
DWORD
*
sp
=
(
DWORD
*
)
teb
->
stack_top
;
*--
sp
=
(
DWORD
)
teb
;
void
**
sp
=
(
void
*
*
)
teb
->
stack_top
;
*--
sp
=
teb
;
*--
sp
=
0
;
*--
sp
=
(
DWORD
)
SYSDEPS_StartThread
;
__asm__
(
"pushl %2;
\n\t
"
/* RFPROC|R
MEM
*/
*--
sp
=
SYSDEPS_StartThread
;
__asm__
__volatile__
(
"pushl %2;
\n\t
"
/* RFPROC|R
FMEM|RFFDG
*/
"pushl $0;
\n\t
"
/* 0 ? */
"movl %1,%%eax;
\n\t
"
/* SYS_rfork */
".byte 0x9a; .long 0; .word 7;
\n\t
"
/* lcall 7:0... FreeBSD syscall */
"cmpl $0, %%edx;
\n\t
"
"je 1f;
\n\t
"
"movl %0,%%esp;
\n\t
"
/*
father
-> new thread */
"movl %0,%%esp;
\n\t
"
/*
child
-> new thread */
"ret;
\n
"
"1:
\n\t
"
/*
child
-> caller thread */
"1:
\n\t
"
/*
parent
-> caller thread */
"addl $8,%%esp"
:
:
"r"
(
sp
),
"g"
(
SYS_rfork
),
"g"
(
RFPROC
|
RFMEM
)
:
"r"
(
sp
),
"g"
(
SYS_rfork
),
"g"
(
RFPROC
|
RFMEM
|
RFFDG
)
:
"eax"
,
"edx"
);
close
(
teb
->
socket
);
/* close the child socket in the parent */
return
0
;
#endif
...
...
@@ -202,15 +202,14 @@ int SYSDEPS_SpawnThread( TEB *teb )
* SYSDEPS_ExitThread
*
* Exit a running thread; must not return.
* Must not make any reference to the thread structures (THDB etc.) as
* they have already been deleted.
*/
void
SYSDEPS_ExitThread
(
void
)
void
SYSDEPS_ExitThread
(
int
status
)
{
#if !defined(__i386__) && defined(HAVE__LWP_CREATE)
#ifdef HAVE__LWP_CREATE
close
(
NtCurrentTeb
()
->
socket
);
_lwp_exit
();
#endif
_exit
(
0
);
_exit
(
status
);
}
...
...
scheduler/thread.c
View file @
12f29b50
...
...
@@ -336,8 +336,23 @@ HANDLE WINAPI CreateThread16( SECURITY_ATTRIBUTES *sa, DWORD stack,
*/
void
WINAPI
ExitThread
(
DWORD
code
)
/* [in] Exit code for this thread */
{
MODULE_DllThreadDetach
(
NULL
);
TerminateThread
(
GetCurrentThread
(),
code
);
struct
terminate_thread_request
*
req
=
get_req_buffer
();
/* send the exit code to the server */
req
->
handle
=
GetCurrentThread
();
req
->
exit_code
=
code
;
server_call
(
REQ_TERMINATE_THREAD
);
if
(
req
->
last
)
{
MODULE_DllProcessDetach
(
TRUE
,
(
LPVOID
)
1
);
TASK_KillTask
(
0
);
exit
(
code
);
}
else
{
MODULE_DllThreadDetach
(
NULL
);
SYSDEPS_ExitThread
(
code
);
}
}
...
...
@@ -590,10 +605,16 @@ BOOL WINAPI TerminateThread(
HANDLE
handle
,
/* [in] Handle to thread */
DWORD
exitcode
)
/* [in] Exit code for thread */
{
BOOL
ret
;
struct
terminate_thread_request
*
req
=
get_req_buffer
();
req
->
handle
=
handle
;
req
->
exit_code
=
exitcode
;
return
!
server_call
(
REQ_TERMINATE_THREAD
);
if
((
ret
=
!
server_call
(
REQ_TERMINATE_THREAD
))
&&
req
->
self
)
{
if
(
req
->
last
)
exit
(
exitcode
);
else
SYSDEPS_ExitThread
(
exitcode
);
}
return
ret
;
}
...
...
server/process.c
View file @
12f29b50
...
...
@@ -399,10 +399,16 @@ void resume_process( struct process *process )
}
/* kill a process on the spot */
void
kill_process
(
struct
process
*
process
,
int
exit_code
)
static
void
kill_process
(
struct
process
*
process
,
struct
thread
*
skip
,
int
exit_code
)
{
while
(
process
->
thread_list
)
kill_thread
(
process
->
thread_list
,
exit_code
);
struct
thread
*
thread
=
process
->
thread_list
;
while
(
thread
)
{
struct
thread
*
next
=
thread
->
proc_next
;
thread
->
exit_code
=
exit_code
;
if
(
thread
!=
skip
)
kill_thread
(
thread
,
1
);
thread
=
next
;
}
}
/* kill all processes being debugged by a given thread */
...
...
@@ -416,7 +422,7 @@ void kill_debugged_processes( struct thread *debugger, int exit_code )
process
=
process
->
next
;
if
(
!
process
)
return
;
process
->
debugger
=
NULL
;
kill_process
(
process
,
exit_code
);
kill_process
(
process
,
NULL
,
exit_code
);
}
}
...
...
@@ -678,7 +684,8 @@ DECL_HANDLER(terminate_process)
if
((
process
=
get_process_from_handle
(
req
->
handle
,
PROCESS_TERMINATE
)))
{
kill_process
(
process
,
req
->
exit_code
);
req
->
self
=
(
current
->
process
==
process
);
kill_process
(
process
,
current
,
req
->
exit_code
);
release_object
(
process
);
}
}
...
...
server/process.h
View file @
12f29b50
...
...
@@ -73,7 +73,6 @@ extern void remove_process_thread( struct process *process,
struct
thread
*
thread
);
extern
void
suspend_process
(
struct
process
*
process
);
extern
void
resume_process
(
struct
process
*
process
);
extern
void
kill_process
(
struct
process
*
process
,
int
exit_code
);
extern
void
kill_debugged_processes
(
struct
thread
*
debugger
,
int
exit_code
);
extern
struct
process_snapshot
*
process_snap
(
int
*
count
);
...
...
server/ptrace.c
View file @
12f29b50
...
...
@@ -117,21 +117,21 @@ static int attach_thread( struct thread *thread )
}
/* detach from a Unix thread and kill it */
void
detach_thread
(
struct
thread
*
thread
)
void
detach_thread
(
struct
thread
*
thread
,
int
sig
)
{
if
(
!
thread
->
unix_pid
)
return
;
if
(
thread
->
attached
)
{
/* make sure it is stopped */
if
(
!
(
thread
->
suspend
+
thread
->
process
->
suspend
))
stop_thread
(
thread
);
kill
(
thread
->
unix_pid
,
SIGTERM
);
if
(
sig
)
kill
(
thread
->
unix_pid
,
sig
);
if
(
debug_level
)
fprintf
(
stderr
,
"%08x: *detached*
\n
"
,
(
unsigned
int
)
thread
);
ptrace
(
PTRACE_DETACH
,
thread
->
unix_pid
,
1
,
SIGTERM
);
ptrace
(
PTRACE_DETACH
,
thread
->
unix_pid
,
1
,
sig
);
thread
->
attached
=
0
;
}
else
{
kill
(
thread
->
unix_pid
,
SIGTERM
);
if
(
sig
)
kill
(
thread
->
unix_pid
,
sig
);
if
(
thread
->
suspend
+
thread
->
process
->
suspend
)
continue_thread
(
thread
);
}
}
...
...
server/request.c
View file @
12f29b50
...
...
@@ -98,7 +98,8 @@ void fatal_protocol_error( struct thread *thread, const char *err, ... )
fprintf
(
stderr
,
"Protocol error:%p: "
,
thread
);
vfprintf
(
stderr
,
err
,
args
);
va_end
(
args
);
kill_thread
(
thread
,
PROTOCOL_ERROR
);
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
}
/* die on a fatal error */
...
...
@@ -193,12 +194,13 @@ void read_request( struct thread *thread )
if
(
ret
==
-
1
)
{
perror
(
"recvmsg"
);
kill_thread
(
thread
,
BROKEN_PIPE
);
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
return
;
}
if
(
!
ret
)
/* closed pipe */
{
kill_thread
(
thread
,
BROKEN_PIPE
);
kill_thread
(
thread
,
0
);
return
;
}
fatal_protocol_error
(
thread
,
"partial message received %d/%d
\n
"
,
ret
,
sizeof
(
req
)
);
...
...
@@ -212,7 +214,6 @@ int write_request( struct thread *thread )
if
(
thread
->
pass_fd
==
-
1
)
{
ret
=
write
(
thread
->
obj
.
fd
,
&
thread
->
error
,
sizeof
(
thread
->
error
)
);
if
(
ret
==
sizeof
(
thread
->
error
))
goto
ok
;
}
else
/* we have an fd to send */
{
...
...
@@ -231,20 +232,33 @@ int write_request( struct thread *thread )
ret
=
sendmsg
(
thread
->
obj
.
fd
,
&
msghdr
,
0
);
close
(
thread
->
pass_fd
);
thread
->
pass_fd
=
-
1
;
if
(
ret
==
sizeof
(
thread
->
error
))
goto
ok
;
}
if
(
ret
==
sizeof
(
thread
->
error
))
{
set_select_events
(
&
thread
->
obj
,
POLLIN
);
return
1
;
}
if
(
ret
==
-
1
)
{
if
(
errno
==
EWOULDBLOCK
)
return
0
;
/* not a fatal error */
if
(
errno
!=
EPIPE
)
perror
(
"sendmsg"
);
if
(
errno
==
EPIPE
)
{
kill_thread
(
thread
,
0
);
/* normal death */
}
else
{
perror
(
"sendmsg"
);
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
}
}
else
{
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
fprintf
(
stderr
,
"Partial message sent %d/%d
\n
"
,
ret
,
sizeof
(
thread
->
error
)
);
}
else
fprintf
(
stderr
,
"Partial message sent %d/%d
\n
"
,
ret
,
sizeof
(
thread
->
error
)
);
kill_thread
(
thread
,
BROKEN_PIPE
);
return
-
1
;
ok:
set_select_events
(
&
thread
->
obj
,
POLLIN
);
return
1
;
}
static
void
master_socket_dump
(
struct
object
*
obj
,
int
verbose
)
...
...
server/request.h
View file @
12f29b50
...
...
@@ -16,11 +16,6 @@
/* max request length */
#define MAX_REQUEST_LENGTH 8192
/* exit code passed to remove_client on communication error */
#define OUT_OF_MEMORY -1
#define BROKEN_PIPE -2
#define PROTOCOL_ERROR -3
/* request handler definition */
#define DECL_HANDLER(name) void req_##name( struct name##_request *req )
...
...
server/thread.c
View file @
12f29b50
...
...
@@ -137,7 +137,7 @@ struct thread *create_thread( int fd, struct process *process, int suspend )
thread
->
pass_fd
=
-
1
;
thread
->
state
=
RUNNING
;
thread
->
attached
=
0
;
thread
->
exit_code
=
STILL_ACTIVE
;
thread
->
exit_code
=
0
;
thread
->
next
=
NULL
;
thread
->
prev
=
NULL
;
thread
->
priority
=
THREAD_PRIORITY_NORMAL
;
...
...
@@ -175,7 +175,7 @@ void thread_poll_event( struct object *obj, int event )
struct
thread
*
thread
=
(
struct
thread
*
)
obj
;
assert
(
obj
->
ops
==
&
thread_ops
);
if
(
event
&
(
POLLERR
|
POLLHUP
))
kill_thread
(
thread
,
BROKEN_PIPE
);
if
(
event
&
(
POLLERR
|
POLLHUP
))
kill_thread
(
thread
,
0
);
else
{
if
(
event
&
POLLOUT
)
write_request
(
thread
);
...
...
@@ -556,20 +556,25 @@ static void get_selector_entry( struct thread *thread, int entry,
}
/* kill a thread on the spot */
void
kill_thread
(
struct
thread
*
thread
,
int
exit_code
)
void
kill_thread
(
struct
thread
*
thread
,
int
violent_death
)
{
if
(
thread
->
state
==
TERMINATED
)
return
;
/* already killed */
thread
->
state
=
TERMINATED
;
thread
->
exit_code
=
exit_code
;
if
(
current
==
thread
)
current
=
NULL
;
if
(
debug_level
)
fprintf
(
stderr
,
"%08x: *killed* exit_code=%d
\n
"
,
(
unsigned
int
)
thread
,
exit_code
);
if
(
thread
->
wait
)
end_wait
(
thread
);
fprintf
(
stderr
,
"%08x: *killed* exit_code=%d
\n
"
,
(
unsigned
int
)
thread
,
thread
->
exit_code
);
if
(
thread
->
wait
)
{
end_wait
(
thread
);
/* if it is waiting on the socket, we don't need to send a SIGTERM */
violent_death
=
0
;
}
debug_exit_thread
(
thread
);
abandon_mutexes
(
thread
);
remove_process_thread
(
thread
->
process
,
thread
);
wake_up
(
&
thread
->
obj
,
0
);
detach_thread
(
thread
);
detach_thread
(
thread
,
violent_death
?
SIGTERM
:
0
);
remove_select_user
(
&
thread
->
obj
);
release_object
(
thread
);
}
...
...
@@ -639,9 +644,17 @@ DECL_HANDLER(terminate_thread)
{
struct
thread
*
thread
;
req
->
self
=
0
;
req
->
last
=
0
;
if
((
thread
=
get_thread_from_handle
(
req
->
handle
,
THREAD_TERMINATE
)))
{
kill_thread
(
thread
,
req
->
exit_code
);
thread
->
exit_code
=
req
->
exit_code
;
if
(
thread
!=
current
)
kill_thread
(
thread
,
1
);
else
{
req
->
self
=
1
;
req
->
last
=
(
thread
->
process
->
running_threads
==
1
);
}
release_object
(
thread
);
}
}
...
...
@@ -654,7 +667,7 @@ DECL_HANDLER(get_thread_info)
if
((
thread
=
get_thread_from_handle
(
req
->
handle
,
THREAD_QUERY_INFORMATION
)))
{
req
->
tid
=
thread
;
req
->
exit_code
=
thread
->
exit_code
;
req
->
exit_code
=
(
thread
->
state
==
TERMINATED
)
?
thread
->
exit_code
:
STILL_ACTIVE
;
req
->
priority
=
thread
->
priority
;
release_object
(
thread
);
}
...
...
server/thread.h
View file @
12f29b50
...
...
@@ -74,7 +74,7 @@ extern void suspend_all_threads( void );
extern
void
resume_all_threads
(
void
);
extern
int
add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
extern
void
remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
extern
void
kill_thread
(
struct
thread
*
thread
,
int
exit_code
);
extern
void
kill_thread
(
struct
thread
*
thread
,
int
violent_death
);
extern
void
wake_up
(
struct
object
*
obj
,
int
max
);
extern
int
sleep_on
(
int
count
,
struct
object
*
objects
[],
int
flags
,
int
timeout
,
sleep_reply
func
);
...
...
@@ -85,7 +85,7 @@ extern void sigchld_handler();
extern
void
wait4_thread
(
struct
thread
*
thread
,
int
signal
);
extern
void
stop_thread
(
struct
thread
*
thread
);
extern
void
continue_thread
(
struct
thread
*
thread
);
extern
void
detach_thread
(
struct
thread
*
thread
);
extern
void
detach_thread
(
struct
thread
*
thread
,
int
sig
);
extern
int
suspend_for_ptrace
(
struct
thread
*
thread
);
extern
int
read_thread_int
(
struct
thread
*
thread
,
const
int
*
addr
,
int
*
data
);
extern
int
write_thread_int
(
struct
thread
*
thread
,
int
*
addr
,
int
data
,
unsigned
int
mask
);
...
...
server/trace.c
View file @
12f29b50
...
...
@@ -297,12 +297,23 @@ static void dump_terminate_process_request( const struct terminate_process_reque
fprintf
(
stderr
,
" exit_code=%d"
,
req
->
exit_code
);
}
static
void
dump_terminate_process_reply
(
const
struct
terminate_process_request
*
req
)
{
fprintf
(
stderr
,
" self=%d"
,
req
->
self
);
}
static
void
dump_terminate_thread_request
(
const
struct
terminate_thread_request
*
req
)
{
fprintf
(
stderr
,
" handle=%d,"
,
req
->
handle
);
fprintf
(
stderr
,
" exit_code=%d"
,
req
->
exit_code
);
}
static
void
dump_terminate_thread_reply
(
const
struct
terminate_thread_request
*
req
)
{
fprintf
(
stderr
,
" self=%d,"
,
req
->
self
);
fprintf
(
stderr
,
" last=%d"
,
req
->
last
);
}
static
void
dump_get_process_info_request
(
const
struct
get_process_info_request
*
req
)
{
fprintf
(
stderr
,
" handle=%d"
,
req
->
handle
);
...
...
@@ -1366,8 +1377,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_init_process_done_reply
,
(
dump_func
)
0
,
(
dump_func
)
dump_get_thread_buffer_reply
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
dump_terminate_process_reply
,
(
dump_func
)
dump_terminate_thread_reply
,
(
dump_func
)
dump_get_process_info_reply
,
(
dump_func
)
0
,
(
dump_func
)
dump_get_thread_info_reply
,
...
...
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