Further server optimizations: - merged request and reply structures - build requests directly into the buffer to avoid a copy
diff --git a/scheduler/client.c b/scheduler/client.c index 4f5dbdb..bc62f53 100644 --- a/scheduler/client.c +++ b/scheduler/client.c
@@ -26,6 +26,14 @@ #define SCM_RIGHTS 1 #endif +/* data structure used to pass an fd with sendmsg/recvmsg */ +struct cmsg_fd +{ + int len; /* sizeof structure */ + int level; /* SOL_SOCKET */ + int type; /* SCM_RIGHTS */ + int fd; /* fd to pass */ +}; /*********************************************************************** * CLIENT_Die @@ -39,9 +47,9 @@ } /*********************************************************************** - * CLIENT_ProtocolError + * server_protocol_error */ -void CLIENT_ProtocolError( const char *err, ... ) +void server_protocol_error( const char *err, ... ) { va_list args; @@ -54,9 +62,9 @@ /*********************************************************************** - * CLIENT_perror + * server_perror */ -void CLIENT_perror( const char *err ) +static void server_perror( const char *err ) { fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid ); perror( err ); @@ -71,24 +79,15 @@ */ static void send_request( enum request req ) { - struct header *head = NtCurrentTeb()->buffer; - int ret, seq = NtCurrentTeb()->seq++; - - assert( server_remaining() >= 0 ); - - head->type = req; - head->len = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer; - - NtCurrentTeb()->buffer_args = head + 1; /* reset the args buffer */ - - if ((ret = write( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq)) + int ret; + if ((ret = write( NtCurrentTeb()->socket, &req, sizeof(req) )) == sizeof(req)) return; if (ret == -1) { if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror( "sendmsg" ); + server_perror( "sendmsg" ); } - CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) ); } /*********************************************************************** @@ -98,23 +97,15 @@ */ static void send_request_fd( enum request req, int fd ) { - struct header *head = NtCurrentTeb()->buffer; - int ret, seq = NtCurrentTeb()->seq++; + int ret; #ifndef HAVE_MSGHDR_ACCRIGHTS struct cmsg_fd cmsg; #endif struct msghdr msghdr; struct iovec vec; - assert( server_remaining() >= 0 ); - - head->type = req; - head->len = (char *)NtCurrentTeb()->buffer_args - (char *)NtCurrentTeb()->buffer; - - NtCurrentTeb()->buffer_args = head + 1; /* reset the args buffer */ - - vec.iov_base = &seq; - vec.iov_len = sizeof(seq); + vec.iov_base = &req; + vec.iov_len = sizeof(req); msghdr.msg_name = NULL; msghdr.msg_namelen = 0; @@ -134,13 +125,13 @@ msghdr.msg_flags = 0; #endif /* HAVE_MSGHDR_ACCRIGHTS */ - if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq)) return; + if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(req)) return; if (ret == -1) { if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror( "sendmsg" ); + server_perror( "sendmsg" ); } - CLIENT_ProtocolError( "partial seq sent %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) ); } /*********************************************************************** @@ -148,26 +139,23 @@ * * Wait for a reply from the server. */ -static void wait_reply(void) +static unsigned int wait_reply(void) { - int seq, ret; + int ret; + unsigned int res; for (;;) { - if ((ret = read( NtCurrentTeb()->socket, &seq, sizeof(seq) )) == sizeof(seq)) - { - if (seq != NtCurrentTeb()->seq++) - CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 ); - return; - } + if ((ret = read( NtCurrentTeb()->socket, &res, sizeof(res) )) == sizeof(res)) + return res; if (ret == -1) { if (errno == EINTR) continue; if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror("read"); + server_perror("read"); } if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */ - CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial msg received %d/%d\n", ret, sizeof(res) ); } } @@ -177,17 +165,18 @@ * * Wait for a reply from the server, when a file descriptor is passed. */ -static int wait_reply_fd(void) +static unsigned int wait_reply_fd( int *fd ) { struct iovec vec; - int seq, ret; + int ret; + unsigned int res; #ifdef HAVE_MSGHDR_ACCRIGHTS struct msghdr msghdr; - int fd = -1; - msghdr.msg_accrights = (void *)&fd; - msghdr.msg_accrightslen = sizeof(int); + *fd = -1; + msghdr.msg_accrights = (void *)fd; + msghdr.msg_accrightslen = sizeof(*fd); #else /* HAVE_MSGHDR_ACCRIGHTS */ struct msghdr msghdr; struct cmsg_fd cmsg; @@ -205,29 +194,26 @@ msghdr.msg_namelen = 0; msghdr.msg_iov = &vec; msghdr.msg_iovlen = 1; - vec.iov_base = &seq; - vec.iov_len = sizeof(seq); + vec.iov_base = &res; + vec.iov_len = sizeof(res); for (;;) { - if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(seq)) + if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(res)) { - if (seq != NtCurrentTeb()->seq++) - CLIENT_ProtocolError( "sequence %08x instead of %08x\n", seq, NtCurrentTeb()->seq - 1 ); -#ifdef HAVE_MSGHDR_ACCRIGHTS - return fd; -#else - return cmsg.fd; +#ifndef HAVE_MSGHDR_ACCRIGHTS + *fd = cmsg.fd; #endif + return res; } if (ret == -1) { if (errno == EINTR) continue; if (errno == EPIPE) CLIENT_Die(); - CLIENT_perror("recvmsg"); + server_perror("recvmsg"); } if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */ - CLIENT_ProtocolError( "partial seq received %d/%d\n", ret, sizeof(seq) ); + server_protocol_error( "partial seq received %d/%d\n", ret, sizeof(res) ); } } @@ -239,18 +225,15 @@ */ unsigned int server_call( enum request req ) { - struct header *head; + unsigned int res; send_request( req ); - wait_reply(); - - head = (struct header *)NtCurrentTeb()->buffer; - if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size)) - CLIENT_ProtocolError( "header length %d\n", head->len ); - if (head->type) SetLastError( head->type ); - return head->type; /* error code */ + res = wait_reply(); + if (res) SetLastError( res ); + return res; /* error code */ } + /*********************************************************************** * server_call_fd * @@ -258,125 +241,17 @@ * If *fd is != -1, it will be passed to the server. * If the server passes an fd, it will be stored into *fd. */ -unsigned int server_call_fd( enum request req, int *fd ) +unsigned int server_call_fd( enum request req, int fd_out, int *fd_in ) { - struct header *head; + unsigned int res; - if (*fd == -1) send_request( req ); - else send_request_fd( req, *fd ); - *fd = wait_reply_fd(); + if (fd_out == -1) send_request( req ); + else send_request_fd( req, fd_out ); - head = (struct header *)NtCurrentTeb()->buffer; - if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size)) - CLIENT_ProtocolError( "header length %d\n", head->len ); - if (head->type) SetLastError( head->type ); - return head->type; /* error code */ -} - -/*********************************************************************** - * CLIENT_SendRequest - * - * Send a request to the server. - */ -void CLIENT_SendRequest( enum request req, int pass_fd, - int n, ... /* arg_1, len_1, etc. */ ) -{ - va_list args; - - va_start( args, n ); - while (n--) - { - void *ptr = va_arg( args, void * ); - int len = va_arg( args, int ); - memcpy( server_add_data( len ), ptr, len ); - } - va_end( args ); - - if (pass_fd == -1) send_request( req ); - else - { - send_request_fd( req, pass_fd ); - close( pass_fd ); /* we passed the fd now we can close it */ - } -} - - -/*********************************************************************** - * CLIENT_WaitReply_v - * - * Wait for a reply from the server. - * Returns the error code (or 0 if OK). - */ -static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd, - struct iovec *vec, int veclen ) -{ - struct header *head; - char *ptr; - int i, remaining; - - if (passed_fd) *passed_fd = wait_reply_fd(); - else wait_reply(); - - head = (struct header *)NtCurrentTeb()->buffer; - if ((head->len < sizeof(*head)) || (head->len > NtCurrentTeb()->buffer_size)) - CLIENT_ProtocolError( "header length %d\n", head->len ); - - remaining = head->len - sizeof(*head); - ptr = (char *)(head + 1); - for (i = 0; i < veclen; i++, vec++) - { - int len = MIN( remaining, vec->iov_len ); - memcpy( vec->iov_base, ptr, len ); - ptr += len; - if (!(remaining -= len)) break; - } - if (len) *len = head->len - sizeof(*head); - if (head->type) SetLastError( head->type ); - return head->type; /* error code */ -} - - -/*********************************************************************** - * CLIENT_WaitReply - * - * Wait for a reply from the server. - */ -unsigned int CLIENT_WaitReply( int *len, int *passed_fd, - int n, ... /* arg_1, len_1, etc. */ ) -{ - struct iovec vec[16]; - va_list args; - int i; - - assert( n < 16 ); - va_start( args, n ); - for (i = 0; i < n; i++) - { - vec[i].iov_base = va_arg( args, void * ); - vec[i].iov_len = va_arg( args, int ); - } - va_end( args ); - return CLIENT_WaitReply_v( len, passed_fd, vec, n ); -} - - -/*********************************************************************** - * CLIENT_WaitSimpleReply - * - * Wait for a simple fixed-length reply from the server. - */ -unsigned int CLIENT_WaitSimpleReply( void *reply, int len, int *passed_fd ) -{ - struct iovec vec; - unsigned int ret; - int got; - - vec.iov_base = reply; - vec.iov_len = len; - ret = CLIENT_WaitReply_v( &got, passed_fd, &vec, 1 ); - if (got != len) - CLIENT_ProtocolError( "WaitSimpleReply: len %d != %d\n", len, got ); - return ret; + if (fd_in) res = wait_reply_fd( fd_in ); + else res = wait_reply(); + if (res) SetLastError( res ); + return res; /* error code */ } @@ -427,24 +302,23 @@ */ int CLIENT_InitThread(void) { - struct init_thread_request req; - struct init_thread_reply reply; + struct init_thread_request *req; TEB *teb = NtCurrentTeb(); + int fd; - int fd = wait_reply_fd(); - if (fd == -1) CLIENT_ProtocolError( "no fd passed on first request\n" ); - if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) CLIENT_perror( "lseek" ); + if (wait_reply_fd( &fd ) || (fd == -1)) + server_protocol_error( "no fd passed on first request\n" ); + if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" ); teb->buffer = mmap( 0, teb->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); close( fd ); - if (teb->buffer == (void*)-1) CLIENT_perror( "mmap" ); - teb->buffer_args = (char *)teb->buffer + sizeof(struct header); + if (teb->buffer == (void*)-1) server_perror( "mmap" ); - req.unix_pid = getpid(); - req.teb = teb; - CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return -1; - teb->process->server_pid = reply.pid; - teb->tid = reply.tid; + req = get_req_buffer(); + req->unix_pid = getpid(); + req->teb = teb; + if (server_call( REQ_INIT_THREAD )) return -1; + teb->process->server_pid = req->pid; + teb->tid = req->tid; return 0; } @@ -456,8 +330,9 @@ */ int CLIENT_SetDebug( int level ) { - CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) ); - return CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_debug_request *req = get_req_buffer(); + req->level = level; + return server_call( REQ_SET_DEBUG ); } /*********************************************************************** @@ -467,9 +342,8 @@ */ int CLIENT_DebuggerRequest( int op ) { - struct debugger_request req; - req.op = op; - CLIENT_SendRequest( REQ_DEBUGGER, -1, 1, &req, sizeof(req) ); - return CLIENT_WaitReply( NULL, NULL, 0 ); + struct debugger_request *req = get_req_buffer(); + req->op = op; + return server_call( REQ_DEBUGGER ); }
diff --git a/scheduler/debugger.c b/scheduler/debugger.c index fd96985..e5a4bea 100644 --- a/scheduler/debugger.c +++ b/scheduler/debugger.c
@@ -17,13 +17,12 @@ */ static DWORD DEBUG_SendEvent( int code, void *data, int size ) { - struct send_debug_event_request req; - struct send_debug_event_reply reply; - - req.code = code; - CLIENT_SendRequest( REQ_SEND_DEBUG_EVENT, -1, 2, &req, sizeof(req), data, size ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0; - return reply.status; + DWORD ret = 0; + struct send_debug_event_request *req = get_req_buffer(); + req->code = code; + memcpy( req + 1, data, size ); + if (!server_call( REQ_SEND_DEBUG_EVENT )) ret = req->status; + return ret; } @@ -135,94 +134,74 @@ */ BOOL WINAPI WaitForDebugEvent( LPDEBUG_EVENT event, DWORD timeout ) { - /* size of the event data */ - static const int event_sizes[] = - { - 0, - sizeof(struct debug_event_exception), /* EXCEPTION_DEBUG_EVENT */ - sizeof(struct debug_event_create_thread), /* CREATE_THREAD_DEBUG_EVENT */ - sizeof(struct debug_event_create_process), /* CREATE_PROCESS_DEBUG_EVENT */ - sizeof(struct debug_event_exit), /* EXIT_THREAD_DEBUG_EVENT */ - sizeof(struct debug_event_exit), /* EXIT_PROCESS_DEBUG_EVENT */ - sizeof(struct debug_event_load_dll), /* LOAD_DLL_DEBUG_EVENT */ - sizeof(struct debug_event_unload_dll), /* UNLOAD_DLL_DEBUG_EVENT */ - sizeof(struct debug_event_output_string), /* OUTPUT_DEBUG_STRING_EVENT */ - sizeof(struct debug_event_rip_info) /* RIP_EVENT */ - }; + struct wait_debug_event_request *req = get_req_buffer(); + union debug_event_data *data = (union debug_event_data *)(req + 1); + int i; - struct wait_debug_event_request req; - struct wait_debug_event_reply reply; - union debug_event_data data; - int i, len; + req->timeout = timeout; + if (server_call( REQ_WAIT_DEBUG_EVENT )) return FALSE; + if ((req->code < 0) || (req->code > RIP_EVENT)) + server_protocol_error( "WaitForDebugEvent: bad code %d\n", req->code ); - req.timeout = timeout; - CLIENT_SendRequest( REQ_WAIT_DEBUG_EVENT, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), - &data, sizeof(data) )) return FALSE; - if ((reply.code < 0) || (reply.code > RIP_EVENT)) - CLIENT_ProtocolError( "WaitForDebugEvent: bad code %d\n", reply.code ); - if (len != sizeof(reply) + event_sizes[reply.code]) - CLIENT_ProtocolError( "WaitForDebugEvent: bad len %d for code %d\n", len, reply.code ); - - event->dwDebugEventCode = reply.code; - event->dwProcessId = (DWORD)reply.pid; - event->dwThreadId = (DWORD)reply.tid; - switch(reply.code) + event->dwDebugEventCode = req->code; + event->dwProcessId = (DWORD)req->pid; + event->dwThreadId = (DWORD)req->tid; + switch(req->code) { case EXCEPTION_DEBUG_EVENT: - event->u.Exception.ExceptionRecord.ExceptionCode = data.exception.code; - event->u.Exception.ExceptionRecord.ExceptionFlags = data.exception.flags; - event->u.Exception.ExceptionRecord.ExceptionRecord = data.exception.record; - event->u.Exception.ExceptionRecord.ExceptionAddress = data.exception.addr; - event->u.Exception.ExceptionRecord.NumberParameters = data.exception.nb_params; - for (i = 0; i < data.exception.nb_params; i++) - event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data.exception.params[i]; - event->u.Exception.dwFirstChance = data.exception.first_chance; + event->u.Exception.ExceptionRecord.ExceptionCode = data->exception.code; + event->u.Exception.ExceptionRecord.ExceptionFlags = data->exception.flags; + event->u.Exception.ExceptionRecord.ExceptionRecord = data->exception.record; + event->u.Exception.ExceptionRecord.ExceptionAddress = data->exception.addr; + event->u.Exception.ExceptionRecord.NumberParameters = data->exception.nb_params; + for (i = 0; i < data->exception.nb_params; i++) + event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data->exception.params[i]; + event->u.Exception.dwFirstChance = data->exception.first_chance; break; case CREATE_THREAD_DEBUG_EVENT: - event->u.CreateThread.hThread = data.create_thread.handle; - event->u.CreateThread.lpThreadLocalBase = data.create_thread.teb; - event->u.CreateThread.lpStartAddress = data.create_thread.start; + event->u.CreateThread.hThread = data->create_thread.handle; + event->u.CreateThread.lpThreadLocalBase = data->create_thread.teb; + event->u.CreateThread.lpStartAddress = data->create_thread.start; break; case CREATE_PROCESS_DEBUG_EVENT: - event->u.CreateProcessInfo.hFile = data.create_process.file; - event->u.CreateProcessInfo.hProcess = data.create_process.process; - event->u.CreateProcessInfo.hThread = data.create_process.thread; - event->u.CreateProcessInfo.lpBaseOfImage = data.create_process.base; - event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.create_process.dbg_offset; - event->u.CreateProcessInfo.nDebugInfoSize = data.create_process.dbg_size; - event->u.CreateProcessInfo.lpThreadLocalBase = data.create_process.teb; - event->u.CreateProcessInfo.lpStartAddress = data.create_process.start; - event->u.CreateProcessInfo.lpImageName = data.create_process.name; - event->u.CreateProcessInfo.fUnicode = data.create_process.unicode; - if (data.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0; + event->u.CreateProcessInfo.hFile = data->create_process.file; + event->u.CreateProcessInfo.hProcess = data->create_process.process; + event->u.CreateProcessInfo.hThread = data->create_process.thread; + event->u.CreateProcessInfo.lpBaseOfImage = data->create_process.base; + event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->create_process.dbg_offset; + event->u.CreateProcessInfo.nDebugInfoSize = data->create_process.dbg_size; + event->u.CreateProcessInfo.lpThreadLocalBase = data->create_process.teb; + event->u.CreateProcessInfo.lpStartAddress = data->create_process.start; + event->u.CreateProcessInfo.lpImageName = data->create_process.name; + event->u.CreateProcessInfo.fUnicode = data->create_process.unicode; + if (data->create_process.file == -1) event->u.CreateProcessInfo.hFile = 0; break; case EXIT_THREAD_DEBUG_EVENT: - event->u.ExitThread.dwExitCode = data.exit.exit_code; + event->u.ExitThread.dwExitCode = data->exit.exit_code; break; case EXIT_PROCESS_DEBUG_EVENT: - event->u.ExitProcess.dwExitCode = data.exit.exit_code; + event->u.ExitProcess.dwExitCode = data->exit.exit_code; break; case LOAD_DLL_DEBUG_EVENT: - event->u.LoadDll.hFile = data.load_dll.handle; - event->u.LoadDll.lpBaseOfDll = data.load_dll.base; - event->u.LoadDll.dwDebugInfoFileOffset = data.load_dll.dbg_offset; - event->u.LoadDll.nDebugInfoSize = data.load_dll.dbg_size; - event->u.LoadDll.lpImageName = data.load_dll.name; - event->u.LoadDll.fUnicode = data.load_dll.unicode; - if (data.load_dll.handle == -1) event->u.LoadDll.hFile = 0; + event->u.LoadDll.hFile = data->load_dll.handle; + event->u.LoadDll.lpBaseOfDll = data->load_dll.base; + event->u.LoadDll.dwDebugInfoFileOffset = data->load_dll.dbg_offset; + event->u.LoadDll.nDebugInfoSize = data->load_dll.dbg_size; + event->u.LoadDll.lpImageName = data->load_dll.name; + event->u.LoadDll.fUnicode = data->load_dll.unicode; + if (data->load_dll.handle == -1) event->u.LoadDll.hFile = 0; break; case UNLOAD_DLL_DEBUG_EVENT: - event->u.UnloadDll.lpBaseOfDll = data.unload_dll.base; + event->u.UnloadDll.lpBaseOfDll = data->unload_dll.base; break; case OUTPUT_DEBUG_STRING_EVENT: - event->u.DebugString.lpDebugStringData = data.output_string.string; - event->u.DebugString.fUnicode = data.output_string.unicode; - event->u.DebugString.nDebugStringLength = data.output_string.length; + event->u.DebugString.lpDebugStringData = data->output_string.string; + event->u.DebugString.fUnicode = data->output_string.unicode; + event->u.DebugString.nDebugStringLength = data->output_string.length; break; case RIP_EVENT: - event->u.RipInfo.dwError = data.rip_info.error; - event->u.RipInfo.dwType = data.rip_info.type; + event->u.RipInfo.dwError = data->rip_info.error; + event->u.RipInfo.dwType = data->rip_info.type; break; } return TRUE; @@ -234,13 +213,11 @@ */ BOOL WINAPI ContinueDebugEvent( DWORD pid, DWORD tid, DWORD status ) { - struct continue_debug_event_request req; - - req.pid = (void *)pid; - req.tid = (void *)tid; - req.status = status; - CLIENT_SendRequest( REQ_CONTINUE_DEBUG_EVENT, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct continue_debug_event_request *req = get_req_buffer(); + req->pid = (void *)pid; + req->tid = (void *)tid; + req->status = status; + return !server_call( REQ_CONTINUE_DEBUG_EVENT ); } @@ -249,10 +226,9 @@ */ BOOL WINAPI DebugActiveProcess( DWORD pid ) { - struct debug_process_request req; - req.pid = (void *)pid; - CLIENT_SendRequest( REQ_DEBUG_PROCESS, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct debug_process_request *req = get_req_buffer(); + req->pid = (void *)pid; + return !server_call( REQ_DEBUG_PROCESS ); }
diff --git a/scheduler/event.c b/scheduler/event.c index a145c76..9c37bc3 100644 --- a/scheduler/event.c +++ b/scheduler/event.c
@@ -18,18 +18,16 @@ HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset, BOOL initial_state, LPCSTR name ) { - struct create_event_request req; - struct create_event_reply reply; + struct create_event_request *req = get_req_buffer(); - if (!name) name = ""; - req.manual_reset = manual_reset; - req.initial_state = initial_state; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_CREATE_EVENT, -1, 2, &req, sizeof(req), name, strlen(name)+1 ); + req->manual_reset = manual_reset; + req->initial_state = initial_state; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; - return reply.handle; + server_call( REQ_CREATE_EVENT ); + if (req->handle == -1) return 0; + return req->handle; } @@ -59,16 +57,14 @@ */ HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name ) { - struct open_event_request req; - struct open_event_reply reply; - int len = name ? strlen(name) + 1 : 0; + struct open_event_request *req = get_req_buffer(); - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_EVENT, -1, 2, &req, sizeof(req), name, len ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ - return (HANDLE)reply.handle; + req->access = access; + req->inherit = inherit; + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); + server_call( REQ_OPEN_EVENT ); + if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */ + return req->handle; } @@ -91,12 +87,10 @@ */ static BOOL EVENT_Operation( HANDLE handle, enum event_op op ) { - struct event_op_request req; - - req.handle = handle; - req.op = op; - CLIENT_SendRequest( REQ_EVENT_OP, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct event_op_request *req = get_req_buffer(); + req->handle = handle; + req->op = op; + return !server_call( REQ_EVENT_OP ); }
diff --git a/scheduler/handle.c b/scheduler/handle.c index 98d9c59..8555a46 100644 --- a/scheduler/handle.c +++ b/scheduler/handle.c
@@ -18,11 +18,9 @@ */ BOOL WINAPI CloseHandle( HANDLE handle ) { - struct close_handle_request req; - - req.handle = handle; - CLIENT_SendRequest( REQ_CLOSE_HANDLE, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct close_handle_request *req = get_req_buffer(); + req->handle = handle; + return !server_call( REQ_CLOSE_HANDLE ); } @@ -31,13 +29,10 @@ */ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags ) { - struct get_handle_info_request req; - struct get_handle_info_reply reply; - - req.handle = handle; - CLIENT_SendRequest( REQ_GET_HANDLE_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (flags) *flags = reply.flags; + struct get_handle_info_request *req = get_req_buffer(); + req->handle = handle; + if (server_call( REQ_GET_HANDLE_INFO )) return FALSE; + if (flags) *flags = req->flags; return TRUE; } @@ -47,13 +42,11 @@ */ BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags ) { - struct set_handle_info_request req; - - req.handle = handle; - req.flags = flags; - req.mask = mask; - CLIENT_SendRequest( REQ_SET_HANDLE_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_handle_info_request *req = get_req_buffer(); + req->handle = handle; + req->flags = flags; + req->mask = mask; + return !server_call( REQ_SET_HANDLE_INFO ); } @@ -64,19 +57,17 @@ HANDLE dest_process, HANDLE *dest, DWORD access, BOOL inherit, DWORD options ) { - struct dup_handle_request req; - struct dup_handle_reply reply; + struct dup_handle_request *req = get_req_buffer(); - req.src_process = source_process; - req.src_handle = source; - req.dst_process = dest_process; - req.access = access; - req.inherit = inherit; - req.options = options; + req->src_process = source_process; + req->src_handle = source; + req->dst_process = dest_process; + req->access = access; + req->inherit = inherit; + req->options = options; - CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (dest) *dest = reply.handle; + if (server_call( REQ_DUP_HANDLE )) return FALSE; + if (dest) *dest = req->handle; return TRUE; } @@ -86,19 +77,17 @@ */ HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc) { - struct dup_handle_request req; - struct dup_handle_reply reply; + struct dup_handle_request *req = get_req_buffer(); - req.src_process = GetCurrentProcess(); - req.src_handle = hSrc; - req.dst_process = -1; - req.access = 0; - req.inherit = FALSE; - req.options = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS; + req->src_process = GetCurrentProcess(); + req->src_handle = hSrc; + req->dst_process = -1; + req->access = 0; + req->inherit = FALSE; + req->options = DUP_HANDLE_MAKE_GLOBAL | DUP_HANDLE_SAME_ACCESS; - CLIENT_SendRequest( REQ_DUP_HANDLE, -1, 1, &req, sizeof(req) ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - return reply.handle; + server_call( REQ_DUP_HANDLE ); + return req->handle; } /***********************************************************************
diff --git a/scheduler/mutex.c b/scheduler/mutex.c index 9567495..94110f1 100644 --- a/scheduler/mutex.c +++ b/scheduler/mutex.c
@@ -16,17 +16,15 @@ */ HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name ) { - struct create_mutex_request req; - struct create_mutex_reply reply; + struct create_mutex_request *req = get_req_buffer(); - if (!name) name = ""; - req.owned = owner; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_CREATE_MUTEX, -1, 2, &req, sizeof(req), name, strlen(name)+1 ); + req->owned = owner; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; - return reply.handle; + server_call( REQ_CREATE_MUTEX ); + if (req->handle == -1) return 0; + return req->handle; } @@ -48,16 +46,14 @@ */ HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name ) { - struct open_mutex_request req; - struct open_mutex_reply reply; - int len = name ? strlen(name) + 1 : 0; + struct open_mutex_request *req = get_req_buffer(); - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_MUTEX, -1, 2, &req, sizeof(req), name, len ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ - return reply.handle; + req->access = access; + req->inherit = inherit; + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); + server_call( REQ_OPEN_MUTEX ); + if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */ + return req->handle; } @@ -78,9 +74,7 @@ */ BOOL WINAPI ReleaseMutex( HANDLE handle ) { - struct release_mutex_request req; - - req.handle = handle; - CLIENT_SendRequest( REQ_RELEASE_MUTEX, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct release_mutex_request *req = get_req_buffer(); + req->handle = handle; + return !server_call( REQ_RELEASE_MUTEX ); }
diff --git a/scheduler/pipe.c b/scheduler/pipe.c index 74fff8c..6b018c7 100644 --- a/scheduler/pipe.c +++ b/scheduler/pipe.c
@@ -16,15 +16,11 @@ BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES sa, DWORD size ) { - struct create_pipe_request req; - struct create_pipe_reply reply; - int len; + struct create_pipe_request *req = get_req_buffer(); - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_CREATE_PIPE, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ) != ERROR_SUCCESS) - return FALSE; - *hReadPipe = reply.handle_read; - *hWritePipe = reply.handle_write; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + if (server_call( REQ_CREATE_PIPE )) return FALSE; + *hReadPipe = req->handle_read; + *hWritePipe = req->handle_write; return TRUE; }
diff --git a/scheduler/process.c b/scheduler/process.c index 20d2737..70cc709 100644 --- a/scheduler/process.c +++ b/scheduler/process.c
@@ -74,29 +74,16 @@ } /*********************************************************************** - * PROCESS_QueryInfo - * - * Retrieve information about a process - */ -static BOOL PROCESS_QueryInfo( HANDLE handle, - struct get_process_info_reply *reply ) -{ - struct get_process_info_request req; - req.handle = handle; - CLIENT_SendRequest( REQ_GET_PROCESS_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitSimpleReply( reply, sizeof(*reply), NULL ); -} - -/*********************************************************************** * PROCESS_IsCurrent * * Check if a handle is to the current process */ BOOL PROCESS_IsCurrent( HANDLE handle ) { - struct get_process_info_reply reply; - return (PROCESS_QueryInfo( handle, &reply ) && - (reply.pid == PROCESS_Current()->server_pid)); + struct get_process_info_request *req = get_req_buffer(); + req->handle = handle; + return (!server_call( REQ_GET_PROCESS_INFO ) && + (req->pid == PROCESS_Current()->server_pid)); } @@ -252,21 +239,12 @@ */ static BOOL PROCESS_CreateEnvDB(void) { - struct init_process_request req; - struct init_process_reply reply; + struct init_process_request *req = get_req_buffer(); STARTUPINFOA *startup; ENVDB *env_db; char cmd_line[4096]; - int len; PDB *pdb = PROCESS_Current(); - /* Retrieve startup info from the server */ - - req.dummy = 0; - CLIENT_SendRequest( REQ_INIT_PROCESS, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), cmd_line, sizeof(cmd_line) )) - return FALSE; - /* Allocate the env DB */ if (!(env_db = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB) ))) @@ -278,15 +256,20 @@ if (!(startup = HeapAlloc( pdb->heap, HEAP_ZERO_MEMORY, sizeof(STARTUPINFOA) ))) return FALSE; env_db->startup_info = startup; - startup->dwFlags = reply.start_flags; - startup->wShowWindow = reply.cmd_show; - env_db->hStdin = startup->hStdInput = reply.hstdin; - env_db->hStdout = startup->hStdOutput = reply.hstdout; - env_db->hStderr = startup->hStdError = reply.hstderr; + + /* Retrieve startup info from the server */ + + if (server_call( REQ_INIT_PROCESS )) return FALSE; + startup->dwFlags = req->start_flags; + startup->wShowWindow = req->cmd_show; + env_db->hStdin = startup->hStdInput = req->hstdin; + env_db->hStdout = startup->hStdOutput = req->hstdout; + env_db->hStderr = startup->hStdError = req->hstderr; + lstrcpynA( cmd_line, req->cmdline, sizeof(cmd_line) ); /* Copy the parent environment */ - if (!ENV_InheritEnvironment( pdb, reply.env_ptr )) return FALSE; + if (!ENV_InheritEnvironment( pdb, req->env_ptr )) return FALSE; /* Copy the command line */ @@ -527,8 +510,7 @@ HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE; DWORD exitcode, size; int server_thandle; - struct new_process_request req; - struct new_process_reply reply; + struct new_process_request *req = get_req_buffer(); TEB *teb = NULL; PDB *parent = PROCESS_Current(); PDB *pdb = PROCESS_CreatePDB( parent, inherit ); @@ -538,29 +520,28 @@ /* Create the process on the server side */ - req.inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); - req.inherit_all = inherit; - req.create_flags = flags; - req.start_flags = startup->dwFlags; + req->inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); + req->inherit_all = inherit; + req->create_flags = flags; + req->start_flags = startup->dwFlags; if (startup->dwFlags & STARTF_USESTDHANDLES) { - req.hstdin = startup->hStdInput; - req.hstdout = startup->hStdOutput; - req.hstderr = startup->hStdError; + req->hstdin = startup->hStdInput; + req->hstdout = startup->hStdOutput; + req->hstderr = startup->hStdError; } else { - req.hstdin = GetStdHandle( STD_INPUT_HANDLE ); - req.hstdout = GetStdHandle( STD_OUTPUT_HANDLE ); - req.hstderr = GetStdHandle( STD_ERROR_HANDLE ); + req->hstdin = GetStdHandle( STD_INPUT_HANDLE ); + req->hstdout = GetStdHandle( STD_OUTPUT_HANDLE ); + req->hstderr = GetStdHandle( STD_ERROR_HANDLE ); } - req.cmd_show = startup->wShowWindow; - req.env_ptr = (void*)env; /* FIXME: hack */ - CLIENT_SendRequest( REQ_NEW_PROCESS, -1, 2, - &req, sizeof(req), cmd_line, strlen(cmd_line) + 1 ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; - pdb->server_pid = reply.pid; - info->hProcess = reply.handle; + req->cmd_show = startup->wShowWindow; + req->env_ptr = (void*)env; /* FIXME: hack */ + lstrcpynA( req->cmdline, cmd_line, server_remaining(req->cmdline) ); + if (server_call( REQ_NEW_PROCESS )) goto error; + pdb->server_pid = req->pid; + info->hProcess = req->handle; info->dwProcessId = (DWORD)pdb->server_pid; if ((flags & DEBUG_PROCESS) || @@ -675,11 +656,10 @@ */ BOOL WINAPI TerminateProcess( HANDLE handle, DWORD exit_code ) { - struct terminate_process_request req; - req.handle = handle; - req.exit_code = exit_code; - CLIENT_SendRequest( REQ_TERMINATE_PROCESS, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct terminate_process_request *req = get_req_buffer(); + req->handle = handle; + req->exit_code = exit_code; + return !server_call( REQ_TERMINATE_PROCESS ); } @@ -816,15 +796,14 @@ */ HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id ) { - struct open_process_request req; - struct open_process_reply reply; + HANDLE ret = 0; + struct open_process_request *req = get_req_buffer(); - req.pid = (void *)id; - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_PROCESS, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0; - return reply.handle; + req->pid = (void *)id; + req->access = access; + req->inherit = inherit; + if (!server_call( REQ_OPEN_PROCESS )) ret = req->handle; + return ret; } /********************************************************************* @@ -832,9 +811,11 @@ */ DWORD WINAPI MapProcessHandle( HANDLE handle ) { - struct get_process_info_reply reply; - if ( !PROCESS_QueryInfo( handle, &reply ) ) return 0; - return (DWORD)reply.pid; + DWORD ret = 0; + struct get_process_info_request *req = get_req_buffer(); + req->handle = handle; + if (!server_call( REQ_GET_PROCESS_INFO )) ret = (DWORD)req->pid; + return ret; } /*********************************************************************** @@ -870,12 +851,11 @@ */ BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass ) { - struct set_process_info_request req; - req.handle = hprocess; - req.priority = priorityclass; - req.mask = SET_PROCESS_INFO_PRIORITY; - CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_process_info_request *req = get_req_buffer(); + req->handle = hprocess; + req->priority = priorityclass; + req->mask = SET_PROCESS_INFO_PRIORITY; + return !server_call( REQ_SET_PROCESS_INFO ); } @@ -884,9 +864,11 @@ */ DWORD WINAPI GetPriorityClass(HANDLE hprocess) { - struct get_process_info_reply reply; - if (!PROCESS_QueryInfo( hprocess, &reply )) return 0; - return reply.priority; + DWORD ret = 0; + struct get_process_info_request *req = get_req_buffer(); + req->handle = hprocess; + if (!server_call( REQ_GET_PROCESS_INFO )) ret = req->priority; + return ret; } @@ -895,12 +877,11 @@ */ BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask ) { - struct set_process_info_request req; - req.handle = hProcess; - req.affinity = affmask; - req.mask = SET_PROCESS_INFO_AFFINITY; - CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_process_info_request *req = get_req_buffer(); + req->handle = hProcess; + req->affinity = affmask; + req->mask = SET_PROCESS_INFO_AFFINITY; + return !server_call( REQ_SET_PROCESS_INFO ); } /********************************************************************** @@ -910,11 +891,16 @@ LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask ) { - struct get_process_info_reply reply; - if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE; - if (lpProcessAffinityMask) *lpProcessAffinityMask = reply.process_affinity; - if (lpSystemAffinityMask) *lpSystemAffinityMask = reply.system_affinity; - return TRUE; + BOOL ret = FALSE; + struct get_process_info_request *req = get_req_buffer(); + req->handle = hProcess; + if (!server_call( REQ_GET_PROCESS_INFO )) + { + if (lpProcessAffinityMask) *lpProcessAffinityMask = req->process_affinity; + if (lpSystemAffinityMask) *lpSystemAffinityMask = req->system_affinity; + ret = TRUE; + } + return ret; } @@ -1119,10 +1105,15 @@ HANDLE hProcess, /* [I] handle to the process */ LPDWORD lpExitCode) /* [O] address to receive termination status */ { - struct get_process_info_reply reply; - if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE; - if (lpExitCode) *lpExitCode = reply.exit_code; - return TRUE; + BOOL ret = FALSE; + struct get_process_info_request *req = get_req_buffer(); + req->handle = hProcess; + if (!server_call( REQ_GET_PROCESS_INFO )) + { + if (lpExitCode) *lpExitCode = req->exit_code; + ret = TRUE; + } + return ret; }
diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c index 018606b..890efa8 100644 --- a/scheduler/semaphore.c +++ b/scheduler/semaphore.c
@@ -16,8 +16,7 @@ */ HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name ) { - struct create_semaphore_request req; - struct create_semaphore_reply reply; + struct create_semaphore_request *req = get_req_buffer(); /* Check parameters */ @@ -27,16 +26,14 @@ return 0; } - if (!name) name = ""; - req.initial = (unsigned int)initial; - req.max = (unsigned int)max; - req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - - CLIENT_SendRequest( REQ_CREATE_SEMAPHORE, -1, 2, &req, sizeof(req), name, strlen(name)+1 ); + req->initial = (unsigned int)initial; + req->max = (unsigned int)max; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); SetLastError(0); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; - return reply.handle; + server_call( REQ_CREATE_SEMAPHORE ); + if (req->handle == -1) return 0; + return req->handle; } @@ -58,16 +55,14 @@ */ HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name ) { - struct open_semaphore_request req; - struct open_semaphore_reply reply; - int len = name ? strlen(name) + 1 : 0; + struct open_semaphore_request *req = get_req_buffer(); - req.access = access; - req.inherit = inherit; - CLIENT_SendRequest( REQ_OPEN_SEMAPHORE, -1, 2, &req, sizeof(req), name, len ); - CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ); - if (reply.handle == -1) return 0; /* must return 0 on failure, not -1 */ - return reply.handle; + req->access = access; + req->inherit = inherit; + lstrcpynA( req->name, name ? name : "", server_remaining(req->name) ); + server_call( REQ_OPEN_SEMAPHORE ); + if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */ + return req->handle; } @@ -88,18 +83,16 @@ */ BOOL WINAPI ReleaseSemaphore( HANDLE handle, LONG count, LONG *previous ) { - struct release_semaphore_request req; - struct release_semaphore_reply reply; + struct release_semaphore_request *req = get_req_buffer(); if (count < 0) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } - req.handle = handle; - req.count = (unsigned int)count; - CLIENT_SendRequest( REQ_RELEASE_SEMAPHORE, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (previous) *previous = reply.prev_count; + req->handle = handle; + req->count = (unsigned int)count; + if (server_call( REQ_RELEASE_SEMAPHORE )) return FALSE; + if (previous) *previous = req->prev_count; return TRUE; }
diff --git a/scheduler/synchro.c b/scheduler/synchro.c index 5504656..7c57e51 100644 --- a/scheduler/synchro.c +++ b/scheduler/synchro.c
@@ -17,6 +17,27 @@ #include "x11drv.h" #include "server.h" +/*********************************************************************** + * call_apcs + * + * Call outstanding APCs. + */ +static void call_apcs(void) +{ +#define MAX_APCS 16 + int i; + void *buffer[MAX_APCS * 2]; + struct get_apcs_request *req = get_req_buffer(); + + if (server_call( REQ_GET_APCS ) || !req->count) return; + assert( req->count <= MAX_APCS ); + memcpy( buffer, req->apcs, req->count * 2 * sizeof(req->apcs[0]) ); + for (i = 0; i < req->count * 2; i += 2) + { + PAPCFUNC func = (PAPCFUNC)req->apcs[i]; + if (func) func( (ULONG_PTR)req->apcs[i+1] ); + } +} /*********************************************************************** * Sleep (KERNEL32.679) @@ -73,11 +94,8 @@ BOOL wait_all, DWORD timeout, BOOL alertable ) { - struct select_request req; - struct select_reply reply; - int server_handle[MAXIMUM_WAIT_OBJECTS]; - void *apc[32]; - int i, len; + struct select_request *req = get_req_buffer(); + int i, ret; if (count > MAXIMUM_WAIT_OBJECTS) { @@ -99,32 +117,18 @@ EVENT_Synchronize( FALSE ); } - for (i = 0; i < count; i++) server_handle[i] = handles[i]; + req->count = count; + req->flags = 0; + req->timeout = timeout; + for (i = 0; i < count; i++) req->handles[i] = handles[i]; - req.count = count; - req.flags = 0; - req.timeout = timeout; + if (wait_all) req->flags |= SELECT_ALL; + if (alertable) req->flags |= SELECT_ALERTABLE; + if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT; - if (wait_all) req.flags |= SELECT_ALL; - if (alertable) req.flags |= SELECT_ALERTABLE; - if (timeout != INFINITE) req.flags |= SELECT_TIMEOUT; - - CLIENT_SendRequest( REQ_SELECT, -1, 2, - &req, sizeof(req), - server_handle, count * sizeof(int) ); - CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), - apc, sizeof(apc) ); - if ((reply.signaled == STATUS_USER_APC) && (len > sizeof(reply))) - { - int i; - len -= sizeof(reply); - for (i = 0; i < len / sizeof(void*); i += 2) - { - PAPCFUNC func = (PAPCFUNC)apc[i]; - if ( func ) func( (ULONG_PTR)apc[i+1] ); - } - } - return reply.signaled; + server_call( REQ_SELECT ); + if ((ret = req->signaled) == STATUS_USER_APC) call_apcs(); + return ret; }
diff --git a/scheduler/thread.c b/scheduler/thread.c index 7a5b9de..62e4dc7 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c
@@ -199,8 +199,7 @@ TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, LPSECURITY_ATTRIBUTES sa, int *server_handle ) { - struct new_thread_request request; - struct new_thread_reply reply = { NULL, -1 }; + struct new_thread_request *req = get_req_buffer(); int fd[2]; HANDLE cleanup_object; @@ -217,6 +216,7 @@ /* Allocate the TEB selector (%fs register) */ + *server_handle = -1; teb->teb_sel = SELECTOR_AllocBlock( teb, 0x1000, SEGMENT_DATA, TRUE, FALSE ); if (!teb->teb_sel) goto error; @@ -232,13 +232,12 @@ /* Create the thread on the server side */ - request.pid = teb->process->server_pid; - request.suspend = ((flags & CREATE_SUSPENDED) != 0); - request.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; - teb->tid = reply.tid; - *server_handle = reply.handle; + req->pid = teb->process->server_pid; + req->suspend = ((flags & CREATE_SUSPENDED) != 0); + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + if (server_call_fd( REQ_NEW_THREAD, fd[1], NULL )) goto error; + teb->tid = req->tid; + *server_handle = req->handle; /* Do the rest of the initialization */ @@ -255,7 +254,7 @@ return teb; error: - if (reply.handle != -1) CloseHandle( reply.handle ); + if (*server_handle != -1) CloseHandle( *server_handle ); if (teb->teb_sel) SELECTOR_FreeBlock( teb->teb_sel, 1 ); if (teb->socket != -1) close( teb->socket ); HeapFree( SystemHeap, 0, teb ); @@ -532,13 +531,11 @@ INT WINAPI GetThreadPriority( HANDLE hthread) /* [in] Handle to thread */ { - struct get_thread_info_request req; - struct get_thread_info_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) - return THREAD_PRIORITY_ERROR_RETURN; - return reply.priority; + INT ret = THREAD_PRIORITY_ERROR_RETURN; + struct get_thread_info_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_GET_THREAD_INFO )) ret = req->priority; + return ret; } @@ -553,12 +550,11 @@ HANDLE hthread, /* [in] Handle to thread */ INT priority) /* [in] Thread priority level */ { - struct set_thread_info_request req; - req.handle = hthread; - req.priority = priority; - req.mask = SET_THREAD_INFO_PRIORITY; - CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct set_thread_info_request *req = get_req_buffer(); + req->handle = hthread; + req->priority = priority; + req->mask = SET_THREAD_INFO_PRIORITY; + return !server_call( REQ_SET_THREAD_INFO ); } @@ -567,12 +563,11 @@ */ DWORD WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD dwThreadAffinityMask ) { - struct set_thread_info_request req; - req.handle = hThread; - req.affinity = dwThreadAffinityMask; - req.mask = SET_THREAD_INFO_AFFINITY; - CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitReply( NULL, NULL, 0 )) return 0; + struct set_thread_info_request *req = get_req_buffer(); + req->handle = hThread; + req->affinity = dwThreadAffinityMask; + req->mask = SET_THREAD_INFO_AFFINITY; + if (server_call( REQ_SET_THREAD_INFO )) return 0; return 1; /* FIXME: should return previous value */ } @@ -588,11 +583,10 @@ HANDLE handle, /* [in] Handle to thread */ DWORD exitcode) /* [in] Exit code for thread */ { - struct terminate_thread_request req; - req.handle = handle; - req.exit_code = exitcode; - CLIENT_SendRequest( REQ_TERMINATE_THREAD, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct terminate_thread_request *req = get_req_buffer(); + req->handle = handle; + req->exit_code = exitcode; + return !server_call( REQ_TERMINATE_THREAD ); } @@ -607,13 +601,15 @@ HANDLE hthread, /* [in] Handle to thread */ LPDWORD exitcode) /* [out] Address to receive termination status */ { - struct get_thread_info_request req; - struct get_thread_info_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE; - if (exitcode) *exitcode = reply.exit_code; - return TRUE; + BOOL ret = FALSE; + struct get_thread_info_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_GET_THREAD_INFO )) + { + if (exitcode) *exitcode = req->exit_code; + ret = TRUE; + } + return ret; } @@ -631,12 +627,11 @@ DWORD WINAPI ResumeThread( HANDLE hthread) /* [in] Identifies thread to restart */ { - struct resume_thread_request req; - struct resume_thread_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_RESUME_THREAD, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff; - return reply.count; + DWORD ret = 0xffffffff; + struct resume_thread_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_RESUME_THREAD )) ret = req->count; + return ret; } @@ -650,12 +645,11 @@ DWORD WINAPI SuspendThread( HANDLE hthread) /* [in] Handle to the thread */ { - struct suspend_thread_request req; - struct suspend_thread_reply reply; - req.handle = hthread; - CLIENT_SendRequest( REQ_SUSPEND_THREAD, -1, 1, &req, sizeof(req) ); - if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff; - return reply.count; + DWORD ret = 0xffffffff; + struct suspend_thread_request *req = get_req_buffer(); + req->handle = hthread; + if (!server_call( REQ_SUSPEND_THREAD )) ret = req->count; + return ret; } @@ -664,12 +658,11 @@ */ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data ) { - struct queue_apc_request req; - req.handle = hthread; - req.func = func; - req.param = (void *)data; - CLIENT_SendRequest( REQ_QUEUE_APC, -1, 1, &req, sizeof(req) ); - return !CLIENT_WaitReply( NULL, NULL, 0 ); + struct queue_apc_request *req = get_req_buffer(); + req->handle = hthread; + req->func = func; + req->param = (void *)data; + return !server_call( REQ_QUEUE_APC ); }