Commit 01150d7f authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Move server call functions to the Unix library.

parent 1a743c9a
...@@ -119,7 +119,6 @@ extern void server_init_process_done(void) DECLSPEC_HIDDEN; ...@@ -119,7 +119,6 @@ extern void server_init_process_done(void) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN; extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN; extern void DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN;
extern sigset_t server_block_set DECLSPEC_HIDDEN; extern sigset_t server_block_set DECLSPEC_HIDDEN;
extern unsigned int server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN;
extern void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN; extern void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN;
extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN; extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN;
extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags, extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
......
...@@ -143,98 +143,6 @@ static DECLSPEC_NORETURN void server_protocol_perror( const char *err ) ...@@ -143,98 +143,6 @@ static DECLSPEC_NORETURN void server_protocol_perror( const char *err )
/*********************************************************************** /***********************************************************************
* send_request
*
* Send a request to the server.
*/
static unsigned int send_request( const struct __server_request_info *req )
{
unsigned int i;
int ret;
if (!req->u.req.request_header.request_size)
{
if ((ret = write( ntdll_get_thread_data()->request_fd, &req->u.req,
sizeof(req->u.req) )) == sizeof(req->u.req)) return STATUS_SUCCESS;
}
else
{
struct iovec vec[__SERVER_MAX_DATA+1];
vec[0].iov_base = (void *)&req->u.req;
vec[0].iov_len = sizeof(req->u.req);
for (i = 0; i < req->data_count; i++)
{
vec[i+1].iov_base = (void *)req->data[i].ptr;
vec[i+1].iov_len = req->data[i].size;
}
if ((ret = writev( ntdll_get_thread_data()->request_fd, vec, i+1 )) ==
req->u.req.request_header.request_size + sizeof(req->u.req)) return STATUS_SUCCESS;
}
if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
if (errno == EPIPE) abort_thread(0);
if (errno == EFAULT) return STATUS_ACCESS_VIOLATION;
server_protocol_perror( "write" );
}
/***********************************************************************
* read_reply_data
*
* Read data from the reply buffer; helper for wait_reply.
*/
static void read_reply_data( void *buffer, size_t size )
{
int ret;
for (;;)
{
if ((ret = read( ntdll_get_thread_data()->reply_fd, buffer, size )) > 0)
{
if (!(size -= ret)) return;
buffer = (char *)buffer + ret;
continue;
}
if (!ret) break;
if (errno == EINTR) continue;
if (errno == EPIPE) break;
server_protocol_perror("read");
}
/* the server closed the connection; time to die... */
abort_thread(0);
}
/***********************************************************************
* wait_reply
*
* Wait for a reply from the server.
*/
static inline unsigned int wait_reply( struct __server_request_info *req )
{
read_reply_data( &req->u.reply, sizeof(req->u.reply) );
if (req->u.reply.reply_header.reply_size)
read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size );
return req->u.reply.reply_header.error;
}
/***********************************************************************
* server_call_unlocked
*/
unsigned int server_call_unlocked( void *req_ptr )
{
struct __server_request_info * const req = req_ptr;
unsigned int ret;
if ((ret = send_request( req ))) return ret;
return wait_reply( req );
}
/***********************************************************************
* wine_server_call (NTDLL.@) * wine_server_call (NTDLL.@)
* *
* Perform a server call. * Perform a server call.
...@@ -258,13 +166,7 @@ unsigned int server_call_unlocked( void *req_ptr ) ...@@ -258,13 +166,7 @@ unsigned int server_call_unlocked( void *req_ptr )
*/ */
unsigned int CDECL wine_server_call( void *req_ptr ) unsigned int CDECL wine_server_call( void *req_ptr )
{ {
sigset_t old_set; return unix_funcs->server_call( req_ptr );
unsigned int ret;
pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
ret = server_call_unlocked( req_ptr );
pthread_sigmask( SIG_SETMASK, &old_set, NULL );
return ret;
} }
...@@ -582,7 +484,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT ...@@ -582,7 +484,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
suspend_context = FALSE; /* server owns the context now */ suspend_context = FALSE; /* server owns the context now */
} }
if (context) wine_server_set_reply( req, &server_context, sizeof(server_context) ); if (context) wine_server_set_reply( req, &server_context, sizeof(server_context) );
ret = server_call_unlocked( req ); ret = unix_funcs->server_call_unlocked( req );
apc_handle = reply->apc_handle; apc_handle = reply->apc_handle;
call = reply->call; call = reply->call;
if (wine_server_reply_size( reply )) if (wine_server_reply_size( reply ))
......
...@@ -996,6 +996,8 @@ static struct unix_funcs unix_funcs = ...@@ -996,6 +996,8 @@ static struct unix_funcs unix_funcs =
mmap_remove_reserved_area, mmap_remove_reserved_area,
mmap_is_in_reserved_area, mmap_is_in_reserved_area,
mmap_enum_reserved_areas, mmap_enum_reserved_areas,
server_call_unlocked,
wine_server_call,
server_send_fd, server_send_fd,
server_remove_fd_from_cache, server_remove_fd_from_cache,
server_get_unix_fd, server_get_unix_fd,
......
...@@ -206,6 +206,115 @@ static DECLSPEC_NORETURN void server_protocol_perror( const char *err ) ...@@ -206,6 +206,115 @@ static DECLSPEC_NORETURN void server_protocol_perror( const char *err )
/*********************************************************************** /***********************************************************************
* send_request
*
* Send a request to the server.
*/
static unsigned int send_request( const struct __server_request_info *req )
{
unsigned int i;
int ret;
if (!req->u.req.request_header.request_size)
{
if ((ret = write( ntdll_get_thread_data()->request_fd, &req->u.req,
sizeof(req->u.req) )) == sizeof(req->u.req)) return STATUS_SUCCESS;
}
else
{
struct iovec vec[__SERVER_MAX_DATA+1];
vec[0].iov_base = (void *)&req->u.req;
vec[0].iov_len = sizeof(req->u.req);
for (i = 0; i < req->data_count; i++)
{
vec[i+1].iov_base = (void *)req->data[i].ptr;
vec[i+1].iov_len = req->data[i].size;
}
if ((ret = writev( ntdll_get_thread_data()->request_fd, vec, i+1 )) ==
req->u.req.request_header.request_size + sizeof(req->u.req)) return STATUS_SUCCESS;
}
if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
if (errno == EPIPE) NtTerminateThread( GetCurrentThread(), 0 );
if (errno == EFAULT) return STATUS_ACCESS_VIOLATION;
server_protocol_perror( "write" );
}
/***********************************************************************
* read_reply_data
*
* Read data from the reply buffer; helper for wait_reply.
*/
static void read_reply_data( void *buffer, size_t size )
{
int ret;
for (;;)
{
if ((ret = read( ntdll_get_thread_data()->reply_fd, buffer, size )) > 0)
{
if (!(size -= ret)) return;
buffer = (char *)buffer + ret;
continue;
}
if (!ret) break;
if (errno == EINTR) continue;
if (errno == EPIPE) break;
server_protocol_perror("read");
}
/* the server closed the connection; time to die... */
for (;;) NtTerminateThread( GetCurrentThread(), 0 );
}
/***********************************************************************
* wait_reply
*
* Wait for a reply from the server.
*/
static inline unsigned int wait_reply( struct __server_request_info *req )
{
read_reply_data( &req->u.reply, sizeof(req->u.reply) );
if (req->u.reply.reply_header.reply_size)
read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size );
return req->u.reply.reply_header.error;
}
/***********************************************************************
* server_call_unlocked
*/
unsigned int CDECL server_call_unlocked( void *req_ptr )
{
struct __server_request_info * const req = req_ptr;
unsigned int ret;
if ((ret = send_request( req ))) return ret;
return wait_reply( req );
}
/***********************************************************************
* wine_server_call
*
* Perform a server call.
*/
unsigned int CDECL wine_server_call( void *req_ptr )
{
sigset_t old_set;
unsigned int ret;
pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
ret = server_call_unlocked( req_ptr );
pthread_sigmask( SIG_SETMASK, &old_set, NULL );
return ret;
}
/***********************************************************************
* server_enter_uninterrupted_section * server_enter_uninterrupted_section
*/ */
void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset )
......
...@@ -60,6 +60,7 @@ extern void virtual_init(void) DECLSPEC_HIDDEN; ...@@ -60,6 +60,7 @@ extern void virtual_init(void) DECLSPEC_HIDDEN;
extern void CDECL dbg_init(void) DECLSPEC_HIDDEN; extern void CDECL dbg_init(void) DECLSPEC_HIDDEN;
extern unsigned int CDECL server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN;
extern void CDECL server_send_fd( int fd ) DECLSPEC_HIDDEN; extern void CDECL server_send_fd( int fd ) DECLSPEC_HIDDEN;
extern int CDECL server_remove_fd_from_cache( HANDLE handle ) DECLSPEC_HIDDEN; extern int CDECL server_remove_fd_from_cache( HANDLE handle ) DECLSPEC_HIDDEN;
extern int CDECL server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd, extern int CDECL server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "wine/debug.h" #include "wine/debug.h"
/* increment this when you change the function table */ /* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 9 #define NTDLL_UNIXLIB_VERSION 10
struct unix_funcs struct unix_funcs
{ {
...@@ -51,6 +51,8 @@ struct unix_funcs ...@@ -51,6 +51,8 @@ struct unix_funcs
void *arg, int top_down ); void *arg, int top_down );
/* server functions */ /* server functions */
unsigned int (CDECL *server_call_unlocked)( void *req_ptr );
unsigned int (CDECL *server_call)( void *req_ptr );
void (CDECL *server_send_fd)( int fd ); void (CDECL *server_send_fd)( int fd );
int (CDECL *server_remove_fd_from_cache)( HANDLE handle ); int (CDECL *server_remove_fd_from_cache)( HANDLE handle );
int (CDECL *server_get_unix_fd)( HANDLE handle, unsigned int wanted_access, int *unix_fd, int (CDECL *server_get_unix_fd)( HANDLE handle, unsigned int wanted_access, int *unix_fd,
......
...@@ -2390,7 +2390,7 @@ unsigned int virtual_locked_server_call( void *req_ptr ) ...@@ -2390,7 +2390,7 @@ unsigned int virtual_locked_server_call( void *req_ptr )
server_enter_uninterrupted_section( &csVirtual, &sigset ); server_enter_uninterrupted_section( &csVirtual, &sigset );
if (!(ret = check_write_access( addr, size, &has_write_watch ))) if (!(ret = check_write_access( addr, size, &has_write_watch )))
{ {
ret = server_call_unlocked( req ); ret = unix_funcs->server_call_unlocked( req );
if (has_write_watch) update_write_watches( addr, size, wine_server_reply_size( req )); if (has_write_watch) update_write_watches( addr, size, wine_server_reply_size( req ));
} }
server_leave_uninterrupted_section( &csVirtual, &sigset ); server_leave_uninterrupted_section( &csVirtual, &sigset );
......
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