You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
Rebase against upstream changes.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
From e70c80c4f78ac6306629d79f86d8c1c5439aaa17 Mon Sep 17 00:00:00 2001
|
||||
From 23d528b7e744e69fa5d857be20f188ce5510c088 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cook <ariscop@gmail.com>
|
||||
Date: Thu, 26 Feb 2015 13:10:41 +1100
|
||||
Subject: server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
|
||||
@@ -9,10 +9,10 @@ Subject: server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
|
||||
2 files changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
|
||||
index a86e331..4f51cea 100644
|
||||
index c63d6b1..5e04836 100644
|
||||
--- a/dlls/kernel32/tests/process.c
|
||||
+++ b/dlls/kernel32/tests/process.c
|
||||
@@ -2449,7 +2449,6 @@ static void test_KillOnJobClose(void)
|
||||
@@ -2435,7 +2435,6 @@ static void test_KillOnJobClose(void)
|
||||
CloseHandle(job);
|
||||
|
||||
dwret = WaitForSingleObject(pi.hProcess, 1000);
|
||||
@@ -21,10 +21,10 @@ index a86e331..4f51cea 100644
|
||||
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
|
||||
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 10193ef..89c029e 100644
|
||||
index 569a8fe..38bd977 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -141,6 +141,7 @@ static void job_dump( struct object *obj, int verbose );
|
||||
@@ -140,6 +140,7 @@ static void job_dump( struct object *obj, int verbose );
|
||||
static struct object_type *job_get_type( struct object *obj );
|
||||
static int job_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static unsigned int job_map_access( struct object *obj, unsigned int access );
|
||||
@@ -41,8 +41,8 @@ index 10193ef..89c029e 100644
|
||||
job_destroy /* destroy */
|
||||
};
|
||||
|
||||
@@ -286,6 +287,20 @@ static void terminate_job( struct job *job, int exit_code )
|
||||
job->terminating = 0;
|
||||
@@ -287,6 +288,20 @@ static void terminate_job( struct job *job, int exit_code )
|
||||
wake_up( &job->obj, 0 );
|
||||
}
|
||||
|
||||
+static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
||||
@@ -63,5 +63,5 @@ index 10193ef..89c029e 100644
|
||||
{
|
||||
struct job *job = (struct job *)obj;
|
||||
--
|
||||
2.3.3
|
||||
2.3.5
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
From f478d1b97efc4fe63f8ccc01a2ab214c0bffc579 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Cook <ariscop@gmail.com>
|
||||
Date: Thu, 26 Feb 2015 12:25:23 +1100
|
||||
Subject: server: Implement remaining wineserver calls for job objects.
|
||||
|
||||
---
|
||||
dlls/kernel32/tests/process.c | 2 --
|
||||
dlls/ntdll/sync.c | 29 +++++++++++++++++++++++++----
|
||||
server/process.c | 40 +++++++++++++++++++++++++++++++++++++++-
|
||||
server/process.h | 1 +
|
||||
server/protocol.def | 7 +++++++
|
||||
5 files changed, 72 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
|
||||
index 44e81ba..a86e331 100644
|
||||
--- a/dlls/kernel32/tests/process.c
|
||||
+++ b/dlls/kernel32/tests/process.c
|
||||
@@ -2269,13 +2269,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);
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index a4df88a..400aa7d 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ntdll_misc.h"
|
||||
+#include "winnt.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||
|
||||
@@ -613,8 +614,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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -624,8 +636,17 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
|
||||
NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info,
|
||||
ULONG len, PULONG ret_len )
|
||||
{
|
||||
- FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ TRACE( "%p %u %p %u %p\n", handle, class, info, len, ret_len );
|
||||
+
|
||||
+ if (class >= MaxJobObjectInfoClass)
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ switch (class)
|
||||
+ {
|
||||
+ default:
|
||||
+ FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 5821435..727a682 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -65,6 +65,7 @@ static unsigned int process_map_access( struct object *obj, unsigned int access
|
||||
static struct security_descriptor *process_get_sd( struct object *obj );
|
||||
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 =
|
||||
{
|
||||
@@ -148,6 +149,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 */
|
||||
};
|
||||
@@ -189,6 +191,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;
|
||||
}
|
||||
@@ -252,12 +255,36 @@ 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 )
|
||||
+{
|
||||
+ /* Windows doesn't report completion events for processes
|
||||
+ * terminated by TerminateProcess, we do the same */
|
||||
+ job->terminating = 1;
|
||||
+
|
||||
+ for (;;) /* restart from the beginning of the list every time */
|
||||
+ {
|
||||
+ struct process *process;
|
||||
+
|
||||
+ /* find the first process associcated 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;
|
||||
@@ -1596,6 +1623,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)
|
||||
{
|
||||
diff --git a/server/process.h b/server/process.h
|
||||
index 0cf9514..ae83b0e 100644
|
||||
--- a/server/process.h
|
||||
+++ b/server/process.h
|
||||
@@ -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 };
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 9199c7f..5ecc8d5 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -3530,6 +3530,13 @@ enum coords_relative
|
||||
@END
|
||||
|
||||
|
||||
+/* Terminate all processes associated with the job */
|
||||
+@REQ(terminate_job)
|
||||
+ obj_handle_t handle; /* handle to the job */
|
||||
+ int status; /* exitcode of the process */
|
||||
+@END
|
||||
+
|
||||
+
|
||||
/* Set limit flags on a job */
|
||||
@REQ(set_job_limits)
|
||||
obj_handle_t handle; /* handle to the job */
|
||||
--
|
||||
2.3.3
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
From 55894316559d36c433e8aa8ae6e6957fa651d09a Mon Sep 17 00:00:00 2001
|
||||
From 32940d62072444eb41a918b27aae6e4b48fe555f Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Thu, 12 Mar 2015 22:19:50 +0100
|
||||
Subject: ntdll: Implement NtQueryInformationJobObject stub function.
|
||||
|
||||
---
|
||||
dlls/ntdll/sync.c | 24 +++++++++++++++++++++++-
|
||||
1 file changed, 23 insertions(+), 1 deletion(-)
|
||||
dlls/ntdll/sync.c | 31 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 30 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index 87ff3e0..9a7a6d0 100644
|
||||
index 04c6de30..fb95460 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -636,15 +636,37 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
|
||||
@@ -635,8 +635,37 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
|
||||
NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info,
|
||||
ULONG len, PULONG ret_len )
|
||||
{
|
||||
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION *extended_limit;
|
||||
+ JOBOBJECT_BASIC_LIMIT_INFORMATION *basic_limit;
|
||||
+
|
||||
TRACE( "%p %u %p %u %p\n", handle, class, info, len, ret_len );
|
||||
|
||||
if (class >= MaxJobObjectInfoClass)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
+ FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
|
||||
FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+
|
||||
switch (class)
|
||||
{
|
||||
+ if (class >= MaxJobObjectInfoClass)
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ switch (class)
|
||||
+ {
|
||||
+ case JobObjectExtendedLimitInformation:
|
||||
+ if (len < sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION))
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
@@ -45,11 +44,12 @@ index 87ff3e0..9a7a6d0 100644
|
||||
+ if (ret_len) *ret_len = sizeof(*basic_limit);
|
||||
+ return STATUS_SUCCESS;
|
||||
+
|
||||
default:
|
||||
- FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
+ default:
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
--
|
||||
2.3.3
|
||||
2.3.5
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
From c86188e18efaf5ece7b4d85ccee4089208e392fa Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 28 Feb 2015 06:09:16 +0100
|
||||
Subject: kernel32/tests: Add tests for waiting on an job object.
|
||||
|
||||
---
|
||||
dlls/kernel32/tests/process.c | 85 +++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 85 insertions(+)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
|
||||
index 4f51cea..aaa1a6e 100644
|
||||
--- a/dlls/kernel32/tests/process.c
|
||||
+++ b/dlls/kernel32/tests/process.c
|
||||
@@ -2456,6 +2456,90 @@ static void test_KillOnJobClose(void)
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
|
||||
+static void test_WaitForJobObject(void)
|
||||
+{
|
||||
+ HANDLE job;
|
||||
+ PROCESS_INFORMATION pi;
|
||||
+ BOOL ret;
|
||||
+ DWORD dwret;
|
||||
+
|
||||
+ /* test waiting for a job object when the process is killed */
|
||||
+ job = pCreateJobObjectW(NULL, NULL);
|
||||
+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError());
|
||||
+
|
||||
+ dwret = WaitForSingleObject(job, 100);
|
||||
+ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret);
|
||||
+
|
||||
+ create_process("wait", &pi);
|
||||
+
|
||||
+ ret = pAssignProcessToJobObject(job, pi.hProcess);
|
||||
+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
|
||||
+
|
||||
+ dwret = WaitForSingleObject(job, 100);
|
||||
+ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret);
|
||||
+
|
||||
+ ret = pTerminateJobObject(job, 123);
|
||||
+ ok(ret, "TerminateJobObject error %u\n", GetLastError());
|
||||
+
|
||||
+ dwret = WaitForSingleObject(job, 500);
|
||||
+ todo_wine
|
||||
+ ok(dwret == WAIT_OBJECT_0 || broken(dwret == WAIT_TIMEOUT),
|
||||
+ "WaitForSingleObject returned %u\n", dwret);
|
||||
+
|
||||
+ if (dwret == WAIT_TIMEOUT) /* Win 2000/XP */
|
||||
+ {
|
||||
+ CloseHandle(pi.hProcess);
|
||||
+ CloseHandle(pi.hThread);
|
||||
+ CloseHandle(job);
|
||||
+ todo_wine
|
||||
+ win_skip("TerminateJobObject doesn't signal job, skipping tests\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* the object is not reset immediately */
|
||||
+ dwret = WaitForSingleObject(job, 100);
|
||||
+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
|
||||
+
|
||||
+ CloseHandle(pi.hProcess);
|
||||
+ CloseHandle(pi.hThread);
|
||||
+
|
||||
+ /* creating a new process doesn't reset the signalled state */
|
||||
+ create_process("wait", &pi);
|
||||
+
|
||||
+ ret = pAssignProcessToJobObject(job, pi.hProcess);
|
||||
+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
|
||||
+
|
||||
+ dwret = WaitForSingleObject(job, 100);
|
||||
+ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
|
||||
+
|
||||
+ ret = pTerminateJobObject(job, 123);
|
||||
+ ok(ret, "TerminateJobObject error %u\n", GetLastError());
|
||||
+
|
||||
+ CloseHandle(pi.hProcess);
|
||||
+ CloseHandle(pi.hThread);
|
||||
+
|
||||
+ CloseHandle(job);
|
||||
+
|
||||
+ /* repeat the test, but this time the process terminates properly */
|
||||
+ job = pCreateJobObjectW(NULL, NULL);
|
||||
+ ok(job != NULL, "CreateJobObject error %u\n", GetLastError());
|
||||
+
|
||||
+ dwret = WaitForSingleObject(job, 100);
|
||||
+ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret);
|
||||
+
|
||||
+ create_process("exit", &pi);
|
||||
+
|
||||
+ ret = pAssignProcessToJobObject(job, pi.hProcess);
|
||||
+ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
|
||||
+
|
||||
+ dwret = WaitForSingleObject(job, 100);
|
||||
+ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret);
|
||||
+
|
||||
+ CloseHandle(pi.hProcess);
|
||||
+ CloseHandle(pi.hThread);
|
||||
+ CloseHandle(job);
|
||||
+}
|
||||
+
|
||||
static HANDLE test_AddSelfToJob(void)
|
||||
{
|
||||
HANDLE job;
|
||||
@@ -2676,6 +2760,7 @@ START_TEST(process)
|
||||
test_QueryInformationJobObject();
|
||||
test_CompletionPort();
|
||||
test_KillOnJobClose();
|
||||
+ test_WaitForJobObject();
|
||||
job = test_AddSelfToJob();
|
||||
test_jobInheritance(job);
|
||||
test_BreakawayOk(job);
|
||||
--
|
||||
2.3.3
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
From 6e6cd9108a8f3c0b9d158ac2605e9b0a08b19c71 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 28 Feb 2015 06:58:48 +0100
|
||||
Subject: server: Implement waiting for job objects.
|
||||
|
||||
---
|
||||
dlls/kernel32/tests/process.c | 2 --
|
||||
server/process.c | 7 ++++++-
|
||||
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
|
||||
index aaa1a6e..c325d32 100644
|
||||
--- a/dlls/kernel32/tests/process.c
|
||||
+++ b/dlls/kernel32/tests/process.c
|
||||
@@ -2482,7 +2482,6 @@ static void test_WaitForJobObject(void)
|
||||
ok(ret, "TerminateJobObject error %u\n", GetLastError());
|
||||
|
||||
dwret = WaitForSingleObject(job, 500);
|
||||
- todo_wine
|
||||
ok(dwret == WAIT_OBJECT_0 || broken(dwret == WAIT_TIMEOUT),
|
||||
"WaitForSingleObject returned %u\n", dwret);
|
||||
|
||||
@@ -2491,7 +2490,6 @@ static void test_WaitForJobObject(void)
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(job);
|
||||
- todo_wine
|
||||
win_skip("TerminateJobObject doesn't signal job, skipping tests\n");
|
||||
return;
|
||||
}
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 3ff0be5..f59fe2b 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -151,6 +151,7 @@ struct job
|
||||
int num_processes; /* count of running processes */
|
||||
unsigned int limit_flags; /* limit flags */
|
||||
int terminating; /* job is terminating */
|
||||
+ int signaled; /* job is signaled */
|
||||
struct completion *completion_port; /* associated completion port */
|
||||
apc_param_t completion_key; /* key to send with completion messages */
|
||||
};
|
||||
@@ -193,6 +194,7 @@ static struct job *create_job_object( struct directory *root, const struct unico
|
||||
job->num_processes = 0;
|
||||
job->limit_flags = 0;
|
||||
job->terminating = 0;
|
||||
+ job->signaled = 0;
|
||||
job->completion_port = NULL;
|
||||
job->completion_key = 0;
|
||||
}
|
||||
@@ -284,6 +286,8 @@ static void terminate_job( struct job *job, int exit_code )
|
||||
}
|
||||
|
||||
job->terminating = 0;
|
||||
+ job->signaled = 1;
|
||||
+ wake_up( &job->obj, 0 );
|
||||
}
|
||||
|
||||
static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
|
||||
@@ -320,7 +324,8 @@ static void job_dump( struct object *obj, int verbose )
|
||||
|
||||
static int job_signaled( struct object *obj, struct wait_queue_entry *entry )
|
||||
{
|
||||
- return 0;
|
||||
+ struct job *job = (struct job *)obj;
|
||||
+ return job->signaled;
|
||||
}
|
||||
|
||||
struct ptid_entry
|
||||
--
|
||||
2.3.3
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
Fixes: [33723] EA Origin needs support for job objects
|
||||
Fixes: Properly track handle count of wineserver objects
|
||||
Fixes: Python PIP needs better NtQueryInformationJobObject stub
|
||||
Fixes: [38351] Ignore unsupported job object restrictions
|
||||
Depends: kernel32-Console_Handles
|
||||
Depends: server-OpenProcess
|
||||
Depends: server-Misc_ACL
|
||||
|
||||
Reference in New Issue
Block a user