Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
1d359a58
Commit
1d359a58
authored
Apr 03, 2015
by
Andrew Cook
Committed by
Alexandre Julliard
Apr 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Implement TerminateJobObject.
parent
b413a4e2
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
91 additions
and
6 deletions
+91
-6
process.c
dlls/kernel32/tests/process.c
+0
-2
sync.c
dlls/ntdll/sync.c
+13
-2
server_protocol.h
include/wine/server_protocol.h
+18
-1
process.c
server/process.c
+38
-1
process.h
server/process.h
+1
-0
protocol.def
server/protocol.def
+7
-0
request.h
server/request.h
+5
-0
trace.c
server/trace.c
+9
-0
No files found.
dlls/kernel32/tests/process.c
View file @
1d359a58
...
...
@@ -2255,13 +2255,11 @@ static void test_TerminateJobObject(void)
ok
(
ret
,
"TerminateJobObject error %u
\n
"
,
GetLastError
());
dwret
=
WaitForSingleObject
(
pi
.
hProcess
,
1000
);
todo_wine
ok
(
dwret
==
WAIT_OBJECT_0
,
"WaitForSingleObject returned %u
\n
"
,
dwret
);
if
(
dwret
==
WAIT_TIMEOUT
)
TerminateProcess
(
pi
.
hProcess
,
0
);
ret
=
GetExitCodeProcess
(
pi
.
hProcess
,
&
dwret
);
ok
(
ret
,
"GetExitCodeProcess error %u
\n
"
,
GetLastError
());
todo_wine
ok
(
dwret
==
123
||
broken
(
dwret
==
0
)
/* randomly fails on Win 2000 / XP */
,
"wrong exitcode %u
\n
"
,
dwret
);
...
...
dlls/ntdll/sync.c
View file @
1d359a58
...
...
@@ -613,8 +613,19 @@ NTSTATUS WINAPI NtOpenJobObject( PHANDLE handle, ACCESS_MASK access, const OBJEC
*/
NTSTATUS
WINAPI
NtTerminateJobObject
(
HANDLE
handle
,
NTSTATUS
status
)
{
FIXME
(
"stub: %p %x
\n
"
,
handle
,
status
);
return
STATUS_SUCCESS
;
NTSTATUS
ret
;
TRACE
(
"(%p, %d)
\n
"
,
handle
,
status
);
SERVER_START_REQ
(
terminate_job
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
status
=
status
;
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
return
ret
;
}
/******************************************************************************
...
...
include/wine/server_protocol.h
View file @
1d359a58
...
...
@@ -5156,6 +5156,20 @@ struct set_job_completion_port_reply
};
struct
terminate_job_request
{
struct
request_header
__header
;
obj_handle_t
handle
;
int
status
;
char
__pad_20
[
4
];
};
struct
terminate_job_reply
{
struct
reply_header
__header
;
};
enum
request
{
REQ_new_process
,
...
...
@@ -5419,6 +5433,7 @@ enum request
REQ_process_in_job
,
REQ_set_job_limits
,
REQ_set_job_completion_port
,
REQ_terminate_job
,
REQ_NB_REQUESTS
};
...
...
@@ -5687,6 +5702,7 @@ union generic_request
struct
process_in_job_request
process_in_job_request
;
struct
set_job_limits_request
set_job_limits_request
;
struct
set_job_completion_port_request
set_job_completion_port_request
;
struct
terminate_job_request
terminate_job_request
;
};
union
generic_reply
{
...
...
@@ -5953,8 +5969,9 @@ union generic_reply
struct
process_in_job_reply
process_in_job_reply
;
struct
set_job_limits_reply
set_job_limits_reply
;
struct
set_job_completion_port_reply
set_job_completion_port_reply
;
struct
terminate_job_reply
terminate_job_reply
;
};
#define SERVER_PROTOCOL_VERSION 46
6
#define SERVER_PROTOCOL_VERSION 46
7
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/process.c
View file @
1d359a58
...
...
@@ -64,6 +64,7 @@ static int process_signaled( struct object *obj, struct wait_queue_entry *entry
static
unsigned
int
process_map_access
(
struct
object
*
obj
,
unsigned
int
access
);
static
void
process_poll_event
(
struct
fd
*
fd
,
int
event
);
static
void
process_destroy
(
struct
object
*
obj
);
static
void
terminate_process
(
struct
process
*
process
,
struct
thread
*
skip
,
int
exit_code
);
static
const
struct
object_ops
process_ops
=
{
...
...
@@ -147,6 +148,7 @@ struct job
struct
list
process_list
;
/* list of all processes */
int
num_processes
;
/* count of running processes */
unsigned
int
limit_flags
;
/* limit flags */
int
terminating
;
/* job is terminating */
struct
completion
*
completion_port
;
/* associated completion port */
apc_param_t
completion_key
;
/* key to send with completion messages */
};
...
...
@@ -188,6 +190,7 @@ static struct job *create_job_object( struct directory *root, const struct unico
list_init
(
&
job
->
process_list
);
job
->
num_processes
=
0
;
job
->
limit_flags
=
0
;
job
->
terminating
=
0
;
job
->
completion_port
=
NULL
;
job
->
completion_key
=
0
;
}
...
...
@@ -251,12 +254,35 @@ static void release_job_process( struct process *process )
assert
(
job
->
num_processes
);
job
->
num_processes
--
;
add_job_completion
(
job
,
JOB_OBJECT_MSG_EXIT_PROCESS
,
get_process_id
(
process
)
);
if
(
!
job
->
terminating
)
add_job_completion
(
job
,
JOB_OBJECT_MSG_EXIT_PROCESS
,
get_process_id
(
process
)
);
if
(
!
job
->
num_processes
)
add_job_completion
(
job
,
JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO
,
0
);
}
static
void
terminate_job
(
struct
job
*
job
,
int
exit_code
)
{
/* don't report completion events for terminated processes */
job
->
terminating
=
1
;
for
(;;)
/* restart from the beginning of the list every time */
{
struct
process
*
process
;
/* find the first process associated with this job and still running */
LIST_FOR_EACH_ENTRY
(
process
,
&
job
->
process_list
,
struct
process
,
job_entry
)
{
if
(
process
->
running_threads
)
break
;
}
if
(
&
process
->
job_entry
==
&
job
->
process_list
)
break
;
/* no process found */
assert
(
process
->
job
==
job
);
terminate_process
(
process
,
NULL
,
exit_code
);
}
job
->
terminating
=
0
;
}
static
void
job_destroy
(
struct
object
*
obj
)
{
struct
job
*
job
=
(
struct
job
*
)
obj
;
...
...
@@ -1543,6 +1569,17 @@ DECL_HANDLER(process_in_job)
release_object
(
process
);
}
/* terminate all processes associated with the job */
DECL_HANDLER
(
terminate_job
)
{
struct
job
*
job
=
get_job_obj
(
current
->
process
,
req
->
handle
,
JOB_OBJECT_TERMINATE
);
if
(
!
job
)
return
;
terminate_job
(
job
,
req
->
status
);
release_object
(
job
);
}
/* update limits of the job object */
DECL_HANDLER
(
set_job_limits
)
{
...
...
server/process.h
View file @
1d359a58
...
...
@@ -26,6 +26,7 @@
struct
atom_table
;
struct
handle_table
;
struct
startup_info
;
struct
job
;
/* process startup state */
enum
startup_state
{
STARTUP_IN_PROGRESS
,
STARTUP_DONE
,
STARTUP_ABORTED
};
...
...
server/protocol.def
View file @
1d359a58
...
...
@@ -3544,3 +3544,10 @@ enum coords_relative
obj_handle_t port; /* handle to the completion port */
client_ptr_t key; /* key to send with completion messages */
@END
/* Terminate all processes associated with the job */
@REQ(terminate_job)
obj_handle_t handle; /* handle to the job */
int status; /* process exit code */
@END
server/request.h
View file @
1d359a58
...
...
@@ -367,6 +367,7 @@ DECL_HANDLER(assign_job);
DECL_HANDLER
(
process_in_job
);
DECL_HANDLER
(
set_job_limits
);
DECL_HANDLER
(
set_job_completion_port
);
DECL_HANDLER
(
terminate_job
);
#ifdef WANT_REQUEST_HANDLERS
...
...
@@ -634,6 +635,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_process_in_job
,
(
req_handler
)
req_set_job_limits
,
(
req_handler
)
req_set_job_completion_port
,
(
req_handler
)
req_terminate_job
,
};
C_ASSERT
(
sizeof
(
affinity_t
)
==
8
);
...
...
@@ -2233,6 +2235,9 @@ C_ASSERT( FIELD_OFFSET(struct set_job_completion_port_request, job) == 12 );
C_ASSERT
(
FIELD_OFFSET
(
struct
set_job_completion_port_request
,
port
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_job_completion_port_request
,
key
)
==
24
);
C_ASSERT
(
sizeof
(
struct
set_job_completion_port_request
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
terminate_job_request
,
handle
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
terminate_job_request
,
status
)
==
16
);
C_ASSERT
(
sizeof
(
struct
terminate_job_request
)
==
24
);
#endif
/* WANT_REQUEST_HANDLERS */
...
...
server/trace.c
View file @
1d359a58
...
...
@@ -4133,6 +4133,12 @@ static void dump_set_job_completion_port_request( const struct set_job_completio
dump_uint64
(
", key="
,
&
req
->
key
);
}
static
void
dump_terminate_job_request
(
const
struct
terminate_job_request
*
req
)
{
fprintf
(
stderr
,
" handle=%04x"
,
req
->
handle
);
fprintf
(
stderr
,
", status=%d"
,
req
->
status
);
}
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
dump_new_process_request
,
(
dump_func
)
dump_get_new_process_info_request
,
...
...
@@ -4395,6 +4401,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_process_in_job_request
,
(
dump_func
)
dump_set_job_limits_request
,
(
dump_func
)
dump_set_job_completion_port_request
,
(
dump_func
)
dump_terminate_job_request
,
};
static
const
dump_func
reply_dumpers
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -4659,6 +4666,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL
,
NULL
,
NULL
,
NULL
,
};
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -4923,6 +4931,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"process_in_job"
,
"set_job_limits"
,
"set_job_completion_port"
,
"terminate_job"
,
};
static
const
struct
...
...
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