- Add a default asynchronous I/O implementation.
- Make file objects use it.
diff --git a/server/file.c b/server/file.c
index 8d23795..dd38e19 100644
--- a/server/file.c
+++ b/server/file.c
@@ -60,8 +60,6 @@
struct fd *fd; /* file descriptor for this file */
unsigned int access; /* file access (GENERIC_READ/WRITE) */
unsigned int options; /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
- struct list read_q;
- struct list write_q;
};
static void file_dump( struct object *obj, int verbose );
@@ -69,11 +67,8 @@
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, struct event **event );
static int file_get_info( struct fd *fd );
-static void file_queue_async( struct fd *fd, void *apc, void *user, void* iosb, int type, int count );
-static void file_cancel_async( struct fd *fd );
static const struct object_ops file_ops =
{
@@ -91,11 +86,11 @@
static const struct fd_ops file_fd_ops =
{
file_get_poll_events, /* get_poll_events */
- file_poll_event, /* poll_event */
+ default_poll_event, /* poll_event */
file_flush, /* flush */
file_get_info, /* get_file_info */
- file_queue_async, /* queue_async */
- file_cancel_async /* cancel_async */
+ default_fd_queue_async, /* queue_async */
+ default_fd_cancel_async /* cancel_async */
};
static inline int is_overlapped( const struct file *file )
@@ -164,8 +159,6 @@
file->access = access;
file->options = options;
- list_init( &file->read_q );
- list_init( &file->write_q );
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
if (!(file->fd = alloc_fd( &file_fd_ops, &file->obj )) ||
@@ -233,27 +226,6 @@
return events;
}
-static void file_poll_event( struct fd *fd, int event )
-{
- struct file *file = get_fd_user( fd );
- assert( file->obj.ops == &file_ops );
- if (is_overlapped( file ))
- {
- if (!list_empty( &file->read_q ) && (POLLIN & event) )
- {
- async_terminate_head( &file->read_q, STATUS_ALERTED );
- return;
- }
- if (!list_empty( &file->write_q ) && (POLLOUT & event) )
- {
- async_terminate_head( &file->write_q, STATUS_ALERTED );
- return;
- }
- }
- default_poll_event( fd, event );
-}
-
-
static int file_flush( struct fd *fd, struct event **event )
{
int ret = (fsync( get_unix_fd(fd) ) != -1);
@@ -269,53 +241,6 @@
else return 0;
}
-static void file_queue_async( struct fd *fd, void *apc, void *user, void *iosb,
- int type, int count )
-{
- struct file *file = get_fd_user( fd );
- struct list *queue;
- int events;
-
- assert( file->obj.ops == &file_ops );
-
- if (!is_overlapped( file ))
- {
- set_error( STATUS_INVALID_HANDLE );
- return;
- }
-
- switch (type)
- {
- case ASYNC_TYPE_READ:
- queue = &file->read_q;
- break;
- case ASYNC_TYPE_WRITE:
- queue = &file->write_q;
- break;
- default:
- set_error( STATUS_INVALID_PARAMETER );
- return;
- }
-
- if (!create_async( current, NULL, queue, apc, user, iosb ))
- return;
-
- /* Check if the new pending request can be served immediately */
- events = check_fd_events( fd, file_get_poll_events( fd ) );
- if (events) file_poll_event( fd, events );
-
- set_fd_events( fd, file_get_poll_events( fd ));
-}
-
-static void file_cancel_async( struct fd *fd )
-{
- struct file *file = get_fd_user( fd );
- assert( file->obj.ops == &file_ops );
-
- async_terminate_queue( &file->read_q, STATUS_CANCELLED );
- async_terminate_queue( &file->write_q, STATUS_CANCELLED );
-}
-
static struct fd *file_get_fd( struct object *obj )
{
struct file *file = (struct file *)obj;
@@ -328,11 +253,6 @@
struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
- if (is_overlapped( file ))
- {
- async_terminate_queue( &file->read_q, STATUS_CANCELLED );
- async_terminate_queue( &file->write_q, STATUS_CANCELLED );
- }
if (file->fd) release_object( file->fd );
}