Commit 86113530 authored by Alexandre Julliard's avatar Alexandre Julliard

Added the data structures and macros that will be needed to support

reentrant server requests.
parent 5e7fa021
...@@ -15,6 +15,7 @@ struct _PDB; ...@@ -15,6 +15,7 @@ struct _PDB;
struct __EXCEPTION_FRAME; struct __EXCEPTION_FRAME;
struct _SECURITY_ATTRIBUTES; struct _SECURITY_ATTRIBUTES;
struct tagSYSLEVEL; struct tagSYSLEVEL;
struct server_buffer_info;
/* Thread exception block /* Thread exception block
...@@ -89,17 +90,16 @@ typedef struct _TEB ...@@ -89,17 +90,16 @@ typedef struct _TEB
DWORD unknown6[5]; /* --n 1e8 Unknown */ DWORD unknown6[5]; /* --n 1e8 Unknown */
/* The following are Wine-specific fields (NT: GDI stuff) */ /* The following are Wine-specific fields (NT: GDI stuff) */
struct _TEB *next; /* --3 1fc Global thread list */ DWORD cleanup; /* --3 1fc Cleanup service handle */
DWORD cleanup; /* --3 200 Cleanup service handle */ int socket; /* --3 200 Socket for server communication */
int socket; /* --3 204 Socket for server communication */ void *buffer; /* --3 204 Buffer shared with server */
void *buffer; /* --3 208 Buffer shared with server */ struct server_buffer_info *buffer_info; /* --3 208 Buffer information */
int buffer_size; /* --3 20c Size of server buffer */ void *debug_info; /* --3 20c Info for debugstr functions */
void *debug_info; /* --3 210 Info for debugstr functions */ void *pthread_data; /* --3 210 Data for pthread emulation */
void *pthread_data; /* --3 214 Data for pthread emulation */
/* here is plenty space for wine specific fields (don't forget to change pad6!!) */ /* here is plenty space for wine specific fields (don't forget to change pad6!!) */
/* the following are nt specific fields */ /* the following are nt specific fields */
DWORD pad6[632]; /* --n 218 */ DWORD pad6[633]; /* --n 214 */
UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */ UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */
USHORT StaticUnicodeBuffer[261]; /* -2- c00 used by advapi32 */ USHORT StaticUnicodeBuffer[261]; /* -2- c00 used by advapi32 */
DWORD pad7; /* --n e0c */ DWORD pad7; /* --n e0c */
......
...@@ -111,21 +111,54 @@ static void server_perror( const char *err ) ...@@ -111,21 +111,54 @@ static void server_perror( const char *err )
/*********************************************************************** /***********************************************************************
* server_exception_handler
*/
DWORD server_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_FRAME *frame,
CONTEXT *context, EXCEPTION_FRAME **pdispatcher )
{
struct __server_exception_frame *server_frame = (struct __server_exception_frame *)frame;
if ((record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))
*NtCurrentTeb()->buffer_info = server_frame->info;
return ExceptionContinueSearch;
}
/***********************************************************************
* server_alloc_req
*/
void *server_alloc_req( size_t fixed_size, size_t var_size )
{
unsigned int pos = NtCurrentTeb()->buffer_info->cur_pos;
union generic_request *req = (union generic_request *)((char *)NtCurrentTeb()->buffer + pos);
size_t size = sizeof(*req) + var_size;
assert( fixed_size <= sizeof(*req) );
if ((char *)req + size > (char *)NtCurrentTeb()->buffer_info)
server_protocol_error( "buffer overflow %d bytes\n",
(char *)req + size - (char *)NtCurrentTeb()->buffer_info );
NtCurrentTeb()->buffer_info->cur_pos = pos + size;
req->header.fixed_size = fixed_size;
req->header.var_size = var_size;
return req;
}
/***********************************************************************
* send_request * send_request
* *
* Send a request to the server. * Send a request to the server.
*/ */
static void send_request( enum request req ) static void send_request( enum request req, struct request_header *header )
{ {
int ret; header->req = req;
if ((ret = write( NtCurrentTeb()->socket, &req, sizeof(req) )) == sizeof(req)) NtCurrentTeb()->buffer_info->cur_req = (char *)header - (char *)NtCurrentTeb()->buffer;
return; /* write a single byte; the value is ignored anyway */
if (ret == -1) if (write( NtCurrentTeb()->socket, header, 1 ) == -1)
{ {
if (errno == EPIPE) SYSDEPS_ExitThread(0); if (errno == EPIPE) SYSDEPS_ExitThread(0);
server_perror( "sendmsg" ); server_perror( "sendmsg" );
} }
server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
} }
/*********************************************************************** /***********************************************************************
...@@ -133,17 +166,17 @@ static void send_request( enum request req ) ...@@ -133,17 +166,17 @@ static void send_request( enum request req )
* *
* Send a request to the server, passing a file descriptor. * Send a request to the server, passing a file descriptor.
*/ */
static void send_request_fd( enum request req, int fd ) static void send_request_fd( enum request req, struct request_header *header, int fd )
{ {
int ret;
#ifndef HAVE_MSGHDR_ACCRIGHTS #ifndef HAVE_MSGHDR_ACCRIGHTS
struct cmsg_fd cmsg; struct cmsg_fd cmsg;
#endif #endif
struct msghdr msghdr; struct msghdr msghdr;
struct iovec vec; struct iovec vec;
vec.iov_base = (void *)&req; /* write a single byte; the value is ignored anyway */
vec.iov_len = sizeof(req); vec.iov_base = (void *)header;
vec.iov_len = 1;
msghdr.msg_name = NULL; msghdr.msg_name = NULL;
msghdr.msg_namelen = 0; msghdr.msg_namelen = 0;
...@@ -163,13 +196,13 @@ static void send_request_fd( enum request req, int fd ) ...@@ -163,13 +196,13 @@ static void send_request_fd( enum request req, int fd )
msghdr.msg_flags = 0; msghdr.msg_flags = 0;
#endif /* HAVE_MSGHDR_ACCRIGHTS */ #endif /* HAVE_MSGHDR_ACCRIGHTS */
if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(req)) return; header->req = req;
if (ret == -1)
if (sendmsg( NtCurrentTeb()->socket, &msghdr, 0 ) == -1)
{ {
if (errno == EPIPE) SYSDEPS_ExitThread(0); if (errno == EPIPE) SYSDEPS_ExitThread(0);
server_perror( "sendmsg" ); server_perror( "sendmsg" );
} }
server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
} }
/*********************************************************************** /***********************************************************************
...@@ -177,24 +210,19 @@ static void send_request_fd( enum request req, int fd ) ...@@ -177,24 +210,19 @@ static void send_request_fd( enum request req, int fd )
* *
* Wait for a reply from the server. * Wait for a reply from the server.
*/ */
static unsigned int wait_reply(void) static void wait_reply(void)
{ {
int ret; int ret;
unsigned int res; char dummy[1];
for (;;) for (;;)
{ {
if ((ret = read( NtCurrentTeb()->socket, &res, sizeof(res) )) == sizeof(res)) if ((ret = read( NtCurrentTeb()->socket, dummy, 1 )) > 0) return;
return res;
if (!ret) break; if (!ret) break;
if (ret == -1)
{
if (errno == EINTR) continue; if (errno == EINTR) continue;
if (errno == EPIPE) break; if (errno == EPIPE) break;
server_perror("read"); server_perror("read");
} }
server_protocol_error( "partial msg received %d/%d\n", ret, sizeof(res) );
}
/* the server closed the connection; time to die... */ /* the server closed the connection; time to die... */
SYSDEPS_ExitThread(0); SYSDEPS_ExitThread(0);
} }
...@@ -205,11 +233,11 @@ static unsigned int wait_reply(void) ...@@ -205,11 +233,11 @@ static unsigned int wait_reply(void)
* *
* Wait for a reply from the server, when a file descriptor is passed. * Wait for a reply from the server, when a file descriptor is passed.
*/ */
static unsigned int wait_reply_fd( int *fd ) static void wait_reply_fd( int *fd )
{ {
struct iovec vec; struct iovec vec;
int ret; int ret;
unsigned int res; char dummy[1];
#ifdef HAVE_MSGHDR_ACCRIGHTS #ifdef HAVE_MSGHDR_ACCRIGHTS
struct msghdr msghdr; struct msghdr msghdr;
...@@ -234,27 +262,23 @@ static unsigned int wait_reply_fd( int *fd ) ...@@ -234,27 +262,23 @@ static unsigned int wait_reply_fd( int *fd )
msghdr.msg_namelen = 0; msghdr.msg_namelen = 0;
msghdr.msg_iov = &vec; msghdr.msg_iov = &vec;
msghdr.msg_iovlen = 1; msghdr.msg_iovlen = 1;
vec.iov_base = (void *)&res; vec.iov_base = (void *)dummy;
vec.iov_len = sizeof(res); vec.iov_len = 1;
for (;;) for (;;)
{ {
if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(res)) if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) > 0)
{ {
#ifndef HAVE_MSGHDR_ACCRIGHTS #ifndef HAVE_MSGHDR_ACCRIGHTS
*fd = cmsg.fd; *fd = cmsg.fd;
#endif #endif
return res; return;
} }
if (!ret) break; if (!ret) break;
if (ret == -1)
{
if (errno == EINTR) continue; if (errno == EINTR) continue;
if (errno == EPIPE) break; if (errno == EPIPE) break;
server_perror("recvmsg"); server_perror("recvmsg");
} }
server_protocol_error( "partial seq received %d/%d\n", ret, sizeof(res) );
}
/* the server closed the connection; time to die... */ /* the server closed the connection; time to die... */
SYSDEPS_ExitThread(0); SYSDEPS_ExitThread(0);
} }
...@@ -267,8 +291,10 @@ static unsigned int wait_reply_fd( int *fd ) ...@@ -267,8 +291,10 @@ static unsigned int wait_reply_fd( int *fd )
*/ */
unsigned int server_call_noerr( enum request req ) unsigned int server_call_noerr( enum request req )
{ {
send_request( req ); void *req_ptr = get_req_buffer();
return wait_reply(); send_request( req, req_ptr );
wait_reply();
return ((struct request_header *)req_ptr)->error;
} }
...@@ -282,13 +308,16 @@ unsigned int server_call_noerr( enum request req ) ...@@ -282,13 +308,16 @@ unsigned int server_call_noerr( enum request req )
unsigned int server_call_fd( enum request req, int fd_out, int *fd_in ) unsigned int server_call_fd( enum request req, int fd_out, int *fd_in )
{ {
unsigned int res; unsigned int res;
void *req_ptr = get_req_buffer();
if (fd_out == -1) send_request( req, req_ptr );
else send_request_fd( req, req_ptr, fd_out );
if (fd_out == -1) send_request( req ); if (fd_in) wait_reply_fd( fd_in );
else send_request_fd( req, fd_out ); else wait_reply();
if (fd_in) res = wait_reply_fd( fd_in ); if ((res = ((struct request_header *)req_ptr)->error))
else res = wait_reply(); SetLastError( RtlNtStatusToDosError(res) );
if (res) SetLastError( RtlNtStatusToDosError(res) );
return res; /* error code */ return res; /* error code */
} }
...@@ -517,37 +546,44 @@ int CLIENT_InitServer(void) ...@@ -517,37 +546,44 @@ int CLIENT_InitServer(void)
*/ */
int CLIENT_InitThread(void) int CLIENT_InitThread(void)
{ {
struct get_thread_buffer_request *first_req; struct get_thread_buffer_request *req;
struct init_thread_request *req;
TEB *teb = NtCurrentTeb(); TEB *teb = NtCurrentTeb();
int fd; int fd, ret, size;
/* ignore SIGPIPE so that we get a EPIPE error instead */ /* ignore SIGPIPE so that we get a EPIPE error instead */
signal( SIGPIPE, SIG_IGN ); signal( SIGPIPE, SIG_IGN );
if (wait_reply_fd( &fd ) || (fd == -1)) wait_reply_fd( &fd );
server_protocol_error( "no fd passed on first request\n" ); if (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 ); if ((size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" );
teb->buffer = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
close( fd ); close( fd );
if (teb->buffer == (void*)-1) server_perror( "mmap" ); if (teb->buffer == (void*)-1) server_perror( "mmap" );
first_req = teb->buffer; teb->buffer_info = (struct server_buffer_info *)((char *)teb->buffer + size) - 1;
teb->pid = first_req->pid;
teb->tid = first_req->tid; req = (struct get_thread_buffer_request *)teb->buffer;
if (first_req->version != SERVER_PROTOCOL_VERSION) teb->pid = req->pid;
teb->tid = req->tid;
if (req->version != SERVER_PROTOCOL_VERSION)
server_protocol_error( "version mismatch %d/%d.\n" server_protocol_error( "version mismatch %d/%d.\n"
"Your %s binary was not upgraded correctly,\n" "Your %s binary was not upgraded correctly,\n"
"or you have an older one somewhere in your PATH.\n", "or you have an older one somewhere in your PATH.\n",
first_req->version, SERVER_PROTOCOL_VERSION, req->version, SERVER_PROTOCOL_VERSION,
(first_req->version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" ); (req->version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
if (first_req->boot) boot_thread_id = teb->tid; if (req->boot) boot_thread_id = teb->tid;
else if (boot_thread_id == teb->tid) boot_thread_id = 0; else if (boot_thread_id == teb->tid) boot_thread_id = 0;
req = teb->buffer; SERVER_START_REQ
{
struct init_thread_request *req = server_alloc_req( sizeof(*req), 0 );
req->unix_pid = getpid(); req->unix_pid = getpid();
req->teb = teb; req->teb = teb;
req->entry = teb->entry_point; req->entry = teb->entry_point;
return server_call_noerr( REQ_INIT_THREAD ); ret = server_call_noerr( REQ_INIT_THREAD );
}
SERVER_END_REQ;
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -557,9 +593,15 @@ int CLIENT_InitThread(void) ...@@ -557,9 +593,15 @@ int CLIENT_InitThread(void)
*/ */
int CLIENT_BootDone( int debug_level ) int CLIENT_BootDone( int debug_level )
{ {
struct boot_done_request *req = get_req_buffer(); int ret;
SERVER_START_REQ
{
struct boot_done_request *req = server_alloc_req( sizeof(*req), 0 );
req->debug_level = debug_level; req->debug_level = debug_level;
return server_call( REQ_BOOT_DONE ); ret = server_call( REQ_BOOT_DONE );
}
SERVER_END_REQ;
return ret;
} }
......
...@@ -105,7 +105,8 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb ) ...@@ -105,7 +105,8 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
if (teb->socket != -1) close( teb->socket ); if (teb->socket != -1) close( teb->socket );
if (teb->stack_sel) SELECTOR_FreeBlock( teb->stack_sel, 1 ); if (teb->stack_sel) SELECTOR_FreeBlock( teb->stack_sel, 1 );
SELECTOR_FreeBlock( teb->teb_sel, 1 ); SELECTOR_FreeBlock( teb->teb_sel, 1 );
if (teb->buffer) munmap( teb->buffer, teb->buffer_size ); if (teb->buffer) munmap( (void *)teb->buffer,
(char *)(teb->buffer_info+1) - (char *)teb->buffer );
if (teb->debug_info) HeapFree( GetProcessHeap(), 0, teb->debug_info ); if (teb->debug_info) HeapFree( GetProcessHeap(), 0, teb->debug_info );
VirtualFree( teb->stack_base, 0, MEM_RELEASE ); VirtualFree( teb->stack_base, 0, MEM_RELEASE );
} }
......
...@@ -129,11 +129,14 @@ void fatal_perror( const char *err, ... ) ...@@ -129,11 +129,14 @@ void fatal_perror( const char *err, ... )
} }
/* call a request handler */ /* call a request handler */
static inline void call_req_handler( struct thread *thread, enum request req ) static inline void call_req_handler( struct thread *thread )
{ {
enum request req;
current = thread; current = thread;
clear_error(); clear_error();
req = ((struct request_header *)current->buffer)->req;
if (debug_level) trace_request( req ); if (debug_level) trace_request( req );
if (req < REQ_NB_REQUESTS) if (req < REQ_NB_REQUESTS)
...@@ -165,7 +168,7 @@ void send_reply( struct thread *thread ) ...@@ -165,7 +168,7 @@ void send_reply( struct thread *thread )
void read_request( struct thread *thread ) void read_request( struct thread *thread )
{ {
int ret; int ret;
enum request req; char dummy[1];
#ifdef HAVE_MSGHDR_ACCRIGHTS #ifdef HAVE_MSGHDR_ACCRIGHTS
msghdr.msg_accrightslen = sizeof(int); msghdr.msg_accrightslen = sizeof(int);
...@@ -178,43 +181,42 @@ void read_request( struct thread *thread ) ...@@ -178,43 +181,42 @@ void read_request( struct thread *thread )
assert( thread->pass_fd == -1 ); assert( thread->pass_fd == -1 );
myiovec.iov_base = (void *)&req; myiovec.iov_base = dummy;
myiovec.iov_len = sizeof(req); myiovec.iov_len = 1;
ret = recvmsg( thread->obj.fd, &msghdr, 0 ); ret = recvmsg( thread->obj.fd, &msghdr, 0 );
#ifndef HAVE_MSGHDR_ACCRIGHTS #ifndef HAVE_MSGHDR_ACCRIGHTS
thread->pass_fd = cmsg.fd; thread->pass_fd = cmsg.fd;
#endif #endif
if (ret == sizeof(req)) if (ret > 0)
{ {
call_req_handler( thread, req ); call_req_handler( thread );
thread->pass_fd = -1; thread->pass_fd = -1;
return; return;
} }
if (ret == -1)
{
perror("recvmsg");
thread->exit_code = 1;
kill_thread( thread, 1 );
return;
}
if (!ret) /* closed pipe */ if (!ret) /* closed pipe */
{ {
kill_thread( thread, 0 ); kill_thread( thread, 0 );
return; return;
} }
fatal_protocol_error( thread, "partial message received %d/%d\n", ret, sizeof(req) ); perror("recvmsg");
thread->exit_code = 1;
kill_thread( thread, 1 );
} }
/* send a message to a client that is ready to receive something */ /* send a message to a client that is ready to receive something */
int write_request( struct thread *thread ) int write_request( struct thread *thread )
{ {
int ret; int ret;
struct request_header *header = thread->buffer;
header->error = thread->error;
if (thread->pass_fd == -1) if (thread->pass_fd == -1)
{ {
ret = write( thread->obj.fd, &thread->error, sizeof(thread->error) ); /* write a single byte; the value is ignored anyway */
ret = write( thread->obj.fd, header, 1 );
} }
else /* we have an fd to send */ else /* we have an fd to send */
{ {
...@@ -227,20 +229,18 @@ int write_request( struct thread *thread ) ...@@ -227,20 +229,18 @@ int write_request( struct thread *thread )
cmsg.fd = thread->pass_fd; cmsg.fd = thread->pass_fd;
#endif /* HAVE_MSGHDR_ACCRIGHTS */ #endif /* HAVE_MSGHDR_ACCRIGHTS */
myiovec.iov_base = (void *)&thread->error; myiovec.iov_base = (void *)header;
myiovec.iov_len = sizeof(thread->error); myiovec.iov_len = 1;
ret = sendmsg( thread->obj.fd, &msghdr, 0 ); ret = sendmsg( thread->obj.fd, &msghdr, 0 );
close( thread->pass_fd ); close( thread->pass_fd );
thread->pass_fd = -1; thread->pass_fd = -1;
} }
if (ret == sizeof(thread->error)) if (ret > 0)
{ {
set_select_events( &thread->obj, POLLIN ); set_select_events( &thread->obj, POLLIN );
return 1; return 1;
} }
if (ret == -1)
{
if (errno == EWOULDBLOCK) return 0; /* not a fatal error */ if (errno == EWOULDBLOCK) return 0; /* not a fatal error */
if (errno == EPIPE) if (errno == EPIPE)
{ {
...@@ -252,13 +252,6 @@ int write_request( struct thread *thread ) ...@@ -252,13 +252,6 @@ int write_request( struct thread *thread )
thread->exit_code = 1; thread->exit_code = 1;
kill_thread( thread, 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) );
}
return -1; return -1;
} }
......
...@@ -48,17 +48,26 @@ static inline void *get_req_ptr( struct thread *thread ) ...@@ -48,17 +48,26 @@ static inline void *get_req_ptr( struct thread *thread )
return thread->buffer; return thread->buffer;
} }
/* get the request vararg data */
inline static void *get_req_data( const void *req )
{
return ((union generic_request *)req + 1);
}
#define REQUEST_END(req) ((char *)(req) + MAX_REQUEST_LENGTH - sizeof(struct server_buffer_info))
/* get the remaining size in the request buffer for object of a given size */ /* get the remaining size in the request buffer for object of a given size */
static inline int get_req_size( const void *req, const void *ptr, size_t typesize ) static inline int get_req_size( const void *req, const void *ptr, size_t typesize )
{ {
return ((char *)req + MAX_REQUEST_LENGTH - (char *)ptr) / typesize; return (REQUEST_END(req) - (char *)ptr) / typesize;
} }
/* get the length of a request string, without going past the end of the request */ /* get the length of a request string, without going past the end of the request */
static inline size_t get_req_strlen( const void *req, const char *str ) static inline size_t get_req_strlen( const void *req, const char *str )
{ {
const char *p = str; const char *p = str;
while (*p && (p < (char *)req + MAX_REQUEST_LENGTH - 1)) p++; while (*p && (p < REQUEST_END(req) - 1)) p++;
return p - str; return p - str;
} }
...@@ -66,7 +75,7 @@ static inline size_t get_req_strlen( const void *req, const char *str ) ...@@ -66,7 +75,7 @@ static inline size_t get_req_strlen( const void *req, const char *str )
static inline size_t get_req_strlenW( const void *req, const WCHAR *str ) static inline size_t get_req_strlenW( const void *req, const WCHAR *str )
{ {
const WCHAR *p = str; const WCHAR *p = str;
while (*p && (p < (WCHAR *)req + MAX_REQUEST_LENGTH/sizeof(WCHAR) - 1)) p++; while (*p && (p < (WCHAR *)REQUEST_END(req) - 1)) p++;
return p - str; return p - str;
} }
......
...@@ -96,6 +96,7 @@ static int alloc_client_buffer( struct thread *thread ) ...@@ -96,6 +96,7 @@ static int alloc_client_buffer( struct thread *thread )
if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error; if (ftruncate( fd, MAX_REQUEST_LENGTH ) == -1) goto error;
if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE, if ((thread->buffer = mmap( 0, MAX_REQUEST_LENGTH, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0 )) == (void*)-1) goto error; MAP_SHARED, fd, 0 )) == (void*)-1) goto error;
thread->buffer_info = (struct server_buffer_info *)((char *)thread->buffer + MAX_REQUEST_LENGTH) - 1;
/* build the first request into the buffer and send it */ /* build the first request into the buffer and send it */
req = thread->buffer; req = thread->buffer;
req->pid = get_process_id( thread->process ); req->pid = get_process_id( thread->process );
......
...@@ -59,6 +59,7 @@ struct thread ...@@ -59,6 +59,7 @@ struct thread
int affinity; /* affinity mask */ int affinity; /* affinity mask */
int suspend; /* suspend count */ int suspend; /* suspend count */
void *buffer; /* buffer for communication with the client */ void *buffer; /* buffer for communication with the client */
struct server_buffer_info *buffer_info; /* buffer information structure */
enum request last_req; /* last request received (for debugging) */ enum request last_req; /* last request received (for debugging) */
}; };
......
...@@ -787,7 +787,6 @@ static void dump_alloc_console_reply( const struct alloc_console_request *req ) ...@@ -787,7 +787,6 @@ static void dump_alloc_console_reply( const struct alloc_console_request *req )
static void dump_free_console_request( const struct free_console_request *req ) static void dump_free_console_request( const struct free_console_request *req )
{ {
fprintf( stderr, " dummy=%d", req->dummy );
} }
static void dump_open_console_request( const struct open_console_request *req ) static void dump_open_console_request( const struct open_console_request *req )
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
%formats = %formats =
( (
"int" => "%d", "int" => "%d",
"long" => "%ld",
"char" => "%c", "char" => "%c",
"unsigned char" => "%02x", "unsigned char" => "%02x",
"unsigned int" => "%08x", "unsigned int" => "%08x",
...@@ -70,8 +69,13 @@ my @server_lines = (); ...@@ -70,8 +69,13 @@ my @server_lines = ();
push @server_lines, "enum request\n{\n"; push @server_lines, "enum request\n{\n";
foreach $req (@requests) { push @server_lines, " REQ_\U$req,\n"; } foreach $req (@requests) { push @server_lines, " REQ_\U$req,\n"; }
push @server_lines, " REQ_NB_REQUESTS\n};\n"; push @server_lines, " REQ_NB_REQUESTS\n};\n\n";
push @server_lines, "\n#define SERVER_PROTOCOL_VERSION $protocol\n"; push @server_lines, "union generic_request\n{\n";
push @server_lines, " struct request_max_size max_size;\n";
push @server_lines, " struct request_header header;\n";
foreach $req (@requests) { push @server_lines, " struct ${req}_request $req;\n"; }
push @server_lines, "};\n\n";
push @server_lines, "#define SERVER_PROTOCOL_VERSION $protocol\n";
REPLACE_IN_FILE( "include/server.h", @server_lines ); REPLACE_IN_FILE( "include/server.h", @server_lines );
...@@ -98,6 +102,7 @@ sub DO_REQUEST ...@@ -98,6 +102,7 @@ sub DO_REQUEST
my $name = shift; my $name = shift;
my @in_struct = (); my @in_struct = ();
my @out_struct = (); my @out_struct = ();
my $got_header = 0;
while (<SERVER>) while (<SERVER>)
{ {
my ($dir, $type, $var); my ($dir, $type, $var);
...@@ -105,14 +110,34 @@ sub DO_REQUEST ...@@ -105,14 +110,34 @@ sub DO_REQUEST
next if /^{$/; next if /^{$/;
s!/\*.*\*/!!g; s!/\*.*\*/!!g;
next if /^\s*$/; next if /^\s*$/;
/^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/ or die "Unrecognized syntax $_"; if (/REQUEST_HEADER/)
{
die "Duplicated header" if $got_header;
die "Header must be first" if ($#in_struct != -1 || $#out_struct != -1);
$got_header++;
next;
}
if (/^\s*(IN|OUT)\s*VARARG\((\w+),(\w+)\)/)
{
$dir = $1;
$var = $2;
$type = "&" . $3;
}
elsif (/^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/)
{
$dir = $1; $dir = $1;
$type = $2 . ($5 || ""); $type = $2 . ($5 || "");
$var = $4; $var = $4;
die "Unrecognized type $type" unless (defined($formats{$type}) || $5); die "Unrecognized type $type" unless (defined($formats{$type}) || $5);
}
else
{
die "Unrecognized syntax $_";
}
if ($dir =~ /IN/) { push @in_struct, $type, $var; } if ($dir =~ /IN/) { push @in_struct, $type, $var; }
if ($dir =~ /OUT/) { push @out_struct, $type, $var; } if ($dir =~ /OUT/) { push @out_struct, $type, $var; }
} }
die "Missing header" unless $got_header;
push @requests, $name; push @requests, $name;
&DO_DUMP_FUNC( $name, "request", @in_struct); &DO_DUMP_FUNC( $name, "request", @in_struct);
if ($#out_struct >= 0) if ($#out_struct >= 0)
......
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