Further server optimizations:
- merged request and reply structures
- build requests directly into the buffer to avoid a copy
diff --git a/server/file.c b/server/file.c
index 8e9fd80..4b0feae 100644
--- a/server/file.c
+++ b/server/file.c
@@ -47,7 +47,7 @@
static int file_get_read_fd( struct object *obj );
static int file_get_write_fd( struct object *obj );
static int file_flush( struct object *obj );
-static int file_get_info( struct object *obj, struct get_file_info_reply *reply );
+static int file_get_info( struct object *obj, struct get_file_info_request *req );
static void file_destroy( struct object *obj );
static const struct object_ops file_ops =
@@ -208,7 +208,7 @@
struct file *file;
int fd;
- if ((fd = create_anonymous_file()) != -1) return NULL;
+ if ((fd = create_anonymous_file()) == -1) return NULL;
if (!(file = create_file_for_fd( fd, access, 0, 0 ))) close( fd );
return file;
}
@@ -295,7 +295,7 @@
return ret;
}
-static int file_get_info( struct object *obj, struct get_file_info_reply *reply )
+static int file_get_info( struct object *obj, struct get_file_info_request *req )
{
struct stat st;
struct file *file = (struct file *)obj;
@@ -307,19 +307,19 @@
return 0;
}
if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
- S_ISSOCK(st.st_mode) || isatty(file->select.fd)) reply->type = FILE_TYPE_CHAR;
- else reply->type = FILE_TYPE_DISK;
- if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
- else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
- if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
- reply->access_time = st.st_atime;
- reply->write_time = st.st_mtime;
- reply->size_high = 0;
- reply->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size;
- reply->links = st.st_nlink;
- reply->index_high = st.st_dev;
- reply->index_low = st.st_ino;
- reply->serial = 0; /* FIXME */
+ S_ISSOCK(st.st_mode) || isatty(file->select.fd)) req->type = FILE_TYPE_CHAR;
+ else req->type = FILE_TYPE_DISK;
+ if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY;
+ else req->attr = FILE_ATTRIBUTE_ARCHIVE;
+ if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY;
+ req->access_time = st.st_atime;
+ req->write_time = st.st_mtime;
+ req->size_high = 0;
+ req->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size;
+ req->links = st.st_nlink;
+ req->index_high = st.st_dev;
+ req->index_low = st.st_ino;
+ req->serial = 0; /* FIXME */
return 1;
}
@@ -485,71 +485,72 @@
/* FIXME: implement this */
return 1;
}
+
/* create a file */
DECL_HANDLER(create_file)
{
- struct create_file_reply *reply = push_reply_data( current, sizeof(*reply) );
- struct file *file = NULL;
+ size_t len = get_req_strlen( req->name );
+ struct file *file;
- if (fd == -1)
+ req->handle = -1;
+ if ((file = create_file( req->name, len, req->access,
+ req->sharing, req->create, req->attrs )))
{
- size_t len = get_req_strlen();
- file = create_file( get_req_data( len + 1), len, req->access,
- req->sharing, req->create, req->attrs );
- }
- else
- {
- if ((fd = dup(fd)) == -1)
- file_set_error();
- else
- file = create_file_for_fd( fd, req->access, req->sharing, req->attrs );
- }
- if (file)
- {
- reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
+ req->handle = alloc_handle( current->process, file, req->access, req->inherit );
release_object( file );
}
- else reply->handle = -1;
+}
+
+/* allocate a file handle for a Unix fd */
+DECL_HANDLER(alloc_file_handle)
+{
+ struct file *file;
+
+ req->handle = -1;
+ if ((fd = dup(fd)) != -1)
+ {
+ if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 )))
+ {
+ req->handle = alloc_handle( current->process, file, req->access, 0 );
+ release_object( file );
+ }
+ else close( fd );
+ }
+ else file_set_error();
}
/* get a Unix fd to read from a file */
DECL_HANDLER(get_read_fd)
{
struct object *obj;
- int read_fd;
if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
{
- read_fd = obj->ops->get_read_fd( obj );
+ set_reply_fd( current, obj->ops->get_read_fd( obj ) );
release_object( obj );
}
- else read_fd = -1;
- set_reply_fd( current, read_fd );
}
/* get a Unix fd to write to a file */
DECL_HANDLER(get_write_fd)
{
struct object *obj;
- int write_fd;
if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
{
- write_fd = obj->ops->get_write_fd( obj );
+ set_reply_fd( current, obj->ops->get_write_fd( obj ) );
release_object( obj );
}
- else write_fd = -1;
- set_reply_fd( current, write_fd );
}
/* set a file current position */
DECL_HANDLER(set_file_pointer)
{
- struct set_file_pointer_reply reply;
- reply.low = req->low;
- reply.high = req->high;
- set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
- add_reply_data( current, &reply, sizeof(reply) );
+ int high = req->high;
+ int low = req->low;
+ set_file_pointer( req->handle, &low, &high, req->whence );
+ req->new_low = low;
+ req->new_high = high;
}
/* truncate (or extend) a file */
@@ -580,11 +581,10 @@
DECL_HANDLER(get_file_info)
{
struct object *obj;
- struct get_file_info_reply *reply = push_reply_data( current, sizeof(*reply) );
if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
{
- obj->ops->get_file_info( obj, reply );
+ obj->ops->get_file_info( obj, req );
release_object( obj );
}
}