Commit ecd41d1d authored by Andrew Cook's avatar Andrew Cook Committed by Alexandre Julliard

server: Implement job limit flags.

parent e8b9f813
...@@ -2387,6 +2387,7 @@ static void test_CompletionPort(void) ...@@ -2387,6 +2387,7 @@ static void test_CompletionPort(void)
port_info.CompletionKey = job; port_info.CompletionKey = job;
port_info.CompletionPort = port; port_info.CompletionPort = port;
ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info)); ret = pSetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &port_info, sizeof(port_info));
todo_wine
ok(ret, "SetInformationJobObject error %u\n", GetLastError()); ok(ret, "SetInformationJobObject error %u\n", GetLastError());
create_process("wait", &pi); create_process("wait", &pi);
......
...@@ -634,8 +634,46 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c ...@@ -634,8 +634,46 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c
*/ */
NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info, ULONG len ) NTSTATUS WINAPI NtSetInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info, ULONG len )
{ {
FIXME( "stub: %p %u %p %u\n", handle, class, info, len ); NTSTATUS status = STATUS_SUCCESS;
return STATUS_SUCCESS; JOBOBJECT_BASIC_LIMIT_INFORMATION *basic_limit;
ULONG info_size = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION);
DWORD limit_flags = JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS;
TRACE( "(%p, %u, %p, %u)\n", handle, class, info, len );
if (class >= MaxJobObjectInfoClass)
return STATUS_INVALID_PARAMETER;
switch (class)
{
case JobObjectExtendedLimitInformation:
info_size = sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
limit_flags = JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS;
/* fallthrough */
case JobObjectBasicLimitInformation:
if (len != info_size)
return STATUS_INVALID_PARAMETER;
basic_limit = info;
if (basic_limit->LimitFlags & ~limit_flags)
return STATUS_INVALID_PARAMETER;
SERVER_START_REQ( set_job_limits )
{
req->handle = wine_server_obj_handle( handle );
req->limit_flags = basic_limit->LimitFlags;
status = wine_server_call( req );
}
SERVER_END_REQ;
break;
default:
FIXME( "stub: %p %u %p %u\n", handle, class, info, len );
return STATUS_NOT_IMPLEMENTED;
}
return status;
} }
/****************************************************************************** /******************************************************************************
......
...@@ -5127,6 +5127,20 @@ struct process_in_job_reply ...@@ -5127,6 +5127,20 @@ struct process_in_job_reply
}; };
struct set_job_limits_request
{
struct request_header __header;
obj_handle_t handle;
unsigned int limit_flags;
char __pad_20[4];
};
struct set_job_limits_reply
{
struct reply_header __header;
};
enum request enum request
{ {
REQ_new_process, REQ_new_process,
...@@ -5388,6 +5402,7 @@ enum request ...@@ -5388,6 +5402,7 @@ enum request
REQ_create_job, REQ_create_job,
REQ_assign_job, REQ_assign_job,
REQ_process_in_job, REQ_process_in_job,
REQ_set_job_limits,
REQ_NB_REQUESTS REQ_NB_REQUESTS
}; };
...@@ -5654,6 +5669,7 @@ union generic_request ...@@ -5654,6 +5669,7 @@ union generic_request
struct create_job_request create_job_request; struct create_job_request create_job_request;
struct assign_job_request assign_job_request; struct assign_job_request assign_job_request;
struct process_in_job_request process_in_job_request; struct process_in_job_request process_in_job_request;
struct set_job_limits_request set_job_limits_request;
}; };
union generic_reply union generic_reply
{ {
...@@ -5918,8 +5934,9 @@ union generic_reply ...@@ -5918,8 +5934,9 @@ union generic_reply
struct create_job_reply create_job_reply; struct create_job_reply create_job_reply;
struct assign_job_reply assign_job_reply; struct assign_job_reply assign_job_reply;
struct process_in_job_reply process_in_job_reply; struct process_in_job_reply process_in_job_reply;
struct set_job_limits_reply set_job_limits_reply;
}; };
#define SERVER_PROTOCOL_VERSION 463 #define SERVER_PROTOCOL_VERSION 464
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -5610,6 +5610,10 @@ typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION { ...@@ -5610,6 +5610,10 @@ typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000 #define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000
#define JOB_OBJECT_LIMIT_SUBSET_AFFINITY 0x00004000 #define JOB_OBJECT_LIMIT_SUBSET_AFFINITY 0x00004000
#define JOB_OBJECT_LIMIT_VALID_FLAGS 0x0007ffff
#define JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS 0x000000ff
#define JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS 0x00007fff
typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP
{ {
RelationProcessorCore = 0, RelationProcessorCore = 0,
......
...@@ -146,6 +146,7 @@ struct job ...@@ -146,6 +146,7 @@ struct job
struct object obj; /* object header */ struct object obj; /* object header */
struct list process_list; /* list of all processes */ struct list process_list; /* list of all processes */
int num_processes; /* count of running processes */ int num_processes; /* count of running processes */
unsigned int limit_flags; /* limit flags */
}; };
static const struct object_ops job_ops = static const struct object_ops job_ops =
...@@ -184,6 +185,7 @@ static struct job *create_job_object( struct directory *root, const struct unico ...@@ -184,6 +185,7 @@ static struct job *create_job_object( struct directory *root, const struct unico
SACL_SECURITY_INFORMATION ); SACL_SECURITY_INFORMATION );
list_init( &job->process_list ); list_init( &job->process_list );
job->num_processes = 0; job->num_processes = 0;
job->limit_flags = 0;
} }
} }
return job; return job;
...@@ -1506,3 +1508,14 @@ DECL_HANDLER(process_in_job) ...@@ -1506,3 +1508,14 @@ DECL_HANDLER(process_in_job)
} }
release_object( process ); release_object( process );
} }
/* update limits of the job object */
DECL_HANDLER(set_job_limits)
{
struct job *job = get_job_obj( current->process, req->handle, JOB_OBJECT_SET_ATTRIBUTES );
if (!job) return;
job->limit_flags = req->limit_flags;
release_object( job );
}
...@@ -3528,3 +3528,10 @@ enum coords_relative ...@@ -3528,3 +3528,10 @@ enum coords_relative
obj_handle_t job; /* handle to the job */ obj_handle_t job; /* handle to the job */
obj_handle_t process; /* handle to the process */ obj_handle_t process; /* handle to the process */
@END @END
/* Set limit flags on a job */
@REQ(set_job_limits)
obj_handle_t handle; /* handle to the job */
unsigned int limit_flags; /* new limit flags */
@END
...@@ -365,6 +365,7 @@ DECL_HANDLER(set_suspend_context); ...@@ -365,6 +365,7 @@ DECL_HANDLER(set_suspend_context);
DECL_HANDLER(create_job); DECL_HANDLER(create_job);
DECL_HANDLER(assign_job); DECL_HANDLER(assign_job);
DECL_HANDLER(process_in_job); DECL_HANDLER(process_in_job);
DECL_HANDLER(set_job_limits);
#ifdef WANT_REQUEST_HANDLERS #ifdef WANT_REQUEST_HANDLERS
...@@ -630,6 +631,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -630,6 +631,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_create_job, (req_handler)req_create_job,
(req_handler)req_assign_job, (req_handler)req_assign_job,
(req_handler)req_process_in_job, (req_handler)req_process_in_job,
(req_handler)req_set_job_limits,
}; };
C_ASSERT( sizeof(affinity_t) == 8 ); C_ASSERT( sizeof(affinity_t) == 8 );
...@@ -2221,6 +2223,9 @@ C_ASSERT( sizeof(struct assign_job_request) == 24 ); ...@@ -2221,6 +2223,9 @@ C_ASSERT( sizeof(struct assign_job_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct process_in_job_request, job) == 12 ); C_ASSERT( FIELD_OFFSET(struct process_in_job_request, job) == 12 );
C_ASSERT( FIELD_OFFSET(struct process_in_job_request, process) == 16 ); C_ASSERT( FIELD_OFFSET(struct process_in_job_request, process) == 16 );
C_ASSERT( sizeof(struct process_in_job_request) == 24 ); C_ASSERT( sizeof(struct process_in_job_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct set_job_limits_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct set_job_limits_request, limit_flags) == 16 );
C_ASSERT( sizeof(struct set_job_limits_request) == 24 );
#endif /* WANT_REQUEST_HANDLERS */ #endif /* WANT_REQUEST_HANDLERS */
......
...@@ -4119,6 +4119,12 @@ static void dump_process_in_job_request( const struct process_in_job_request *re ...@@ -4119,6 +4119,12 @@ static void dump_process_in_job_request( const struct process_in_job_request *re
fprintf( stderr, ", process=%04x", req->process ); fprintf( stderr, ", process=%04x", req->process );
} }
static void dump_set_job_limits_request( const struct set_job_limits_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", limit_flags=%08x", req->limit_flags );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = { static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request, (dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request, (dump_func)dump_get_new_process_info_request,
...@@ -4379,6 +4385,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -4379,6 +4385,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_job_request, (dump_func)dump_create_job_request,
(dump_func)dump_assign_job_request, (dump_func)dump_assign_job_request,
(dump_func)dump_process_in_job_request, (dump_func)dump_process_in_job_request,
(dump_func)dump_set_job_limits_request,
}; };
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
...@@ -4641,6 +4648,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -4641,6 +4648,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_job_reply, (dump_func)dump_create_job_reply,
NULL, NULL,
NULL, NULL,
NULL,
}; };
static const char * const req_names[REQ_NB_REQUESTS] = { static const char * const req_names[REQ_NB_REQUESTS] = {
...@@ -4903,6 +4911,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -4903,6 +4911,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_job", "create_job",
"assign_job", "assign_job",
"process_in_job", "process_in_job",
"set_job_limits",
}; };
static const struct static const struct
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment