Commit ef8b9462 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

- rewrite of the named pipe code

- allow NtFileFlushBuffers to wait - allow DisconnectNamedPipe to invalidate client cached fd - fix the pipe test now that one extra test passes
parent 35d5d06a
......@@ -754,6 +754,7 @@ BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe)
{
req->handle = hPipe;
ret = !wine_server_call_err( req );
if (ret && reply->fd != -1) close( reply->fd );
}
SERVER_END_REQ;
......
......@@ -90,10 +90,7 @@ void test_CreateNamedPipeA(void)
hFile = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, 0, 0);
todo_wine
{
ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed");
}
/* don't try to do i/o if one side couldn't be opened, as it hangs */
if (hFile != INVALID_HANDLE_VALUE) {
......
......@@ -498,11 +498,19 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile (
NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock )
{
NTSTATUS ret;
HANDLE hEvent = NULL;
SERVER_START_REQ( flush_file )
{
req->handle = hFile;
ret = wine_server_call( req );
hEvent = reply->event;
}
SERVER_END_REQ;
if( !ret && hEvent )
{
ret = NtWaitForSingleObject( hEvent, FALSE, NULL );
NtClose( hEvent );
}
return ret;
}
......@@ -876,6 +876,7 @@ struct flush_file_request
struct flush_file_reply
{
struct reply_header __header;
obj_handle_t event;
};
......@@ -2464,6 +2465,7 @@ struct disconnect_named_pipe_request
struct disconnect_named_pipe_reply
{
struct reply_header __header;
int fd;
};
......@@ -3581,6 +3583,6 @@ union generic_reply
struct get_next_hook_reply get_next_hook_reply;
};
#define SERVER_PROTOCOL_VERSION 105
#define SERVER_PROTOCOL_VERSION 106
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -963,7 +963,7 @@ void default_poll_event( struct fd *fd, int event )
}
/* default flush() routine */
int no_flush( struct fd *fd )
int no_flush( struct fd *fd, struct event **event )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
return 0;
......@@ -1002,10 +1002,15 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl
DECL_HANDLER(flush_file)
{
struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
struct event * event = NULL;
if (fd)
{
fd->fd_ops->flush( fd );
fd->fd_ops->flush( fd, &event );
if( event )
{
reply->event = alloc_handle( current->process, event, SYNCHRONIZE, 0 );
}
release_object( fd );
}
}
......
......@@ -72,7 +72,7 @@ static void file_destroy( struct object *obj );
static int file_get_poll_events( struct fd *fd );
static void file_poll_event( struct fd *fd, int event );
static int file_flush( struct fd *fd );
static int file_flush( struct fd *fd, struct event **event );
static int file_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags );
static void file_queue_async( struct fd *fd, void *ptr, unsigned int status, int type, int count );
......@@ -301,7 +301,7 @@ static void file_poll_event( struct fd *fd, int event )
}
static int file_flush( struct fd *fd )
static int file_flush( struct fd *fd, struct event **event )
{
int ret = (fsync( get_unix_fd(fd) ) != -1);
if (!ret) file_set_error();
......
......@@ -35,7 +35,7 @@ struct fd_ops
/* a poll() event occured */
void (*poll_event)(struct fd *,int event);
/* flush the object buffers */
int (*flush)(struct fd *);
int (*flush)(struct fd *, struct event **);
/* get file information */
int (*get_file_info)(struct fd *,struct get_file_info_reply *, int *flags);
/* queue an async operation - see register_async handler in async.c*/
......@@ -55,12 +55,13 @@ extern int check_fd_events( struct fd *fd, int events );
extern void set_fd_events( struct fd *fd, int events );
extern obj_handle_t lock_fd( struct fd *fd, file_pos_t offset, file_pos_t count, int shared, int wait );
extern void unlock_fd( struct fd *fd, file_pos_t offset, file_pos_t count );
extern int flush_cached_fd( struct process *process, obj_handle_t handle );
extern int default_fd_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void default_fd_remove_queue( struct object *obj, struct wait_queue_entry *entry );
extern int default_fd_signaled( struct object *obj, struct thread *thread );
extern void default_poll_event( struct fd *fd, int event );
extern int no_flush( struct fd *fd );
extern int no_flush( struct fd *fd, struct event **event );
extern int no_get_file_info( struct fd *fd, struct get_file_info_reply *info, int *flags );
extern void no_queue_async( struct fd *fd, void* ptr, unsigned int status, int type, int count );
extern void main_loop(void);
......
......@@ -397,6 +397,20 @@ int get_handle_unix_fd( struct process *process, obj_handle_t handle, unsigned i
return entry->fd;
}
/* remove the cached fd and return it */
int flush_cached_fd( struct process *process, obj_handle_t handle )
{
struct handle_entry *entry = get_handle( process, handle );
int fd = -1;
if (entry)
{
fd = entry->fd;
entry->fd = -1;
}
return fd;
}
/* find the first inherited handle of the given type */
/* this is needed for window stations and desktops (don't ask...) */
obj_handle_t find_inherited_handle( struct process *process, const struct object_ops *ops )
......
......@@ -665,6 +665,8 @@ enum fd_type
/* Flush a file buffers */
@REQ(flush_file)
obj_handle_t handle; /* handle to the file */
@REPLY
obj_handle_t event; /* event set when finished */
@END
......@@ -1739,6 +1741,8 @@ enum message_type
/* Disconnect a named pipe */
@REQ(disconnect_named_pipe)
obj_handle_t handle;
@REPLY
int fd; /* associated fd to close */
@END
......
......@@ -58,7 +58,7 @@ static void serial_destroy(struct object *obj);
static int serial_get_poll_events( struct fd *fd );
static void serial_poll_event( struct fd *fd, int event );
static int serial_get_info( struct fd *fd, struct get_file_info_reply *reply, int *flags );
static int serial_flush( struct fd *fd );
static int serial_flush( struct fd *fd, struct event **event );
static void serial_queue_async(struct fd *fd, void *ptr, unsigned int status, int type, int count);
struct serial
......@@ -329,7 +329,7 @@ static void serial_queue_async(struct fd *fd, void *ptr, unsigned int status, in
set_fd_events ( fd, serial_get_poll_events( fd ));
}
static int serial_flush( struct fd *fd )
static int serial_flush( struct fd *fd, struct event **event )
{
/* MSDN says: If hFile is a handle to a communications device,
* the function only flushes the transmit buffer.
......
......@@ -877,6 +877,11 @@ static void dump_flush_file_request( const struct flush_file_request *req )
fprintf( stderr, " handle=%p", req->handle );
}
static void dump_flush_file_reply( const struct flush_file_reply *req )
{
fprintf( stderr, " event=%p", req->event );
}
static void dump_get_file_info_request( const struct get_file_info_request *req )
{
fprintf( stderr, " handle=%p", req->handle );
......@@ -1993,6 +1998,11 @@ static void dump_disconnect_named_pipe_request( const struct disconnect_named_pi
fprintf( stderr, " handle=%p", req->handle );
}
static void dump_disconnect_named_pipe_reply( const struct disconnect_named_pipe_reply *req )
{
fprintf( stderr, " fd=%d", req->fd );
}
static void dump_get_named_pipe_info_request( const struct get_named_pipe_info_request *req )
{
fprintf( stderr, " handle=%p", req->handle );
......@@ -2660,7 +2670,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_set_file_pointer_reply,
(dump_func)0,
(dump_func)0,
(dump_func)0,
(dump_func)dump_flush_file_reply,
(dump_func)dump_get_file_info_reply,
(dump_func)dump_lock_file_reply,
(dump_func)0,
......@@ -2755,7 +2765,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_named_pipe_reply,
(dump_func)0,
(dump_func)0,
(dump_func)0,
(dump_func)dump_disconnect_named_pipe_reply,
(dump_func)dump_get_named_pipe_info_reply,
(dump_func)dump_create_smb_reply,
(dump_func)dump_get_smb_info_reply,
......
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