Alexandre Julliard : server: Use the file descriptor instead of the file object where possible in memory mappings .
Alexandre Julliard
julliard at winehq.org
Tue Nov 24 12:40:20 CST 2009
Module: wine
Branch: master
Commit: 0f4068ac6fa29276e637aa9a169a475eb8cfe835
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0f4068ac6fa29276e637aa9a169a475eb8cfe835
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Nov 23 16:03:37 2009 +0100
server: Use the file descriptor instead of the file object where possible in memory mappings.
---
server/mapping.c | 67 ++++++++++++++---------------------------------------
1 files changed, 18 insertions(+), 49 deletions(-)
diff --git a/server/mapping.c b/server/mapping.c
index 2c4bc43..67760c9 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -128,14 +128,11 @@ static void init_page_size(void)
/* extend a file beyond the current end of file */
-static int extend_file( struct file *file, file_pos_t new_size )
+static int grow_file( int unix_fd, file_pos_t new_size )
{
static const char zero;
- int unix_fd = get_file_unix_fd( file );
off_t size = new_size;
- if (unix_fd == -1) return 0;
-
if (sizeof(new_size) > sizeof(size) && size != new_size)
{
set_error( STATUS_INVALID_PARAMETER );
@@ -152,30 +149,13 @@ static int extend_file( struct file *file, file_pos_t new_size )
return 0;
}
-/* try to grow the file to the specified size */
-static int grow_file( struct file *file, file_pos_t size )
-{
- struct stat st;
- int unix_fd = get_file_unix_fd( file );
-
- if (unix_fd == -1) return 0;
-
- if (fstat( unix_fd, &st ) == -1)
- {
- file_set_error();
- return 0;
- }
- if (st.st_size >= size) return 1; /* already large enough */
- return extend_file( file, size );
-}
-
/* find the shared PE mapping for a given mapping */
static struct file *get_shared_file( struct mapping *mapping )
{
struct mapping *ptr;
LIST_FOR_EACH_ENTRY( ptr, &shared_list, struct mapping, shared_entry )
- if (is_same_file( ptr->file, mapping->file ))
+ if (is_same_file_fd( ptr->fd, mapping->fd ))
return (struct file *)grab_object( ptr->shared_file );
return NULL;
}
@@ -301,8 +281,8 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
/* create a temp file for the mapping */
if (!(mapping->shared_file = create_temp_file( FILE_GENERIC_READ|FILE_GENERIC_WRITE ))) return 0;
- if (!grow_file( mapping->shared_file, total_size )) goto error;
if ((shared_fd = get_file_unix_fd( mapping->shared_file )) == -1) goto error;
+ if (!grow_file( shared_fd, total_size )) goto error;
if (!(buffer = malloc( max_size ))) goto error;
@@ -343,7 +323,7 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
}
/* retrieve the mapping parameters for an executable (PE) image */
-static int get_image_params( struct mapping *mapping )
+static int get_image_params( struct mapping *mapping, int unix_fd )
{
IMAGE_DOS_HEADER dos;
IMAGE_SECTION_HEADER *sec = NULL;
@@ -357,14 +337,11 @@ static int get_image_params( struct mapping *mapping )
IMAGE_OPTIONAL_HEADER64 hdr64;
} opt;
} nt;
- struct fd *fd;
off_t pos;
- int unix_fd, size;
+ int size;
/* load the headers */
- if (!(fd = mapping_get_fd( &mapping->obj ))) return 0;
- if ((unix_fd = get_unix_fd( fd )) == -1) goto error;
if (pread( unix_fd, &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error;
if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error;
pos = dos.e_lfanew;
@@ -406,33 +383,22 @@ static int get_image_params( struct mapping *mapping )
mapping->protect = VPROT_IMAGE;
free( sec );
- release_object( fd );
return 1;
error:
free( sec );
- release_object( fd );
set_error( STATUS_INVALID_FILE_FOR_SECTION );
return 0;
}
-/* get the size of the unix file associated with the mapping */
-static inline int get_file_size( struct file *file, mem_size_t *size )
-{
- struct stat st;
- int unix_fd = get_file_unix_fd( file );
-
- if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 0;
- *size = st.st_size;
- return 1;
-}
-
static struct object *create_mapping( struct directory *root, const struct unicode_str *name,
unsigned int attr, mem_size_t size, int protect,
obj_handle_t handle, const struct security_descriptor *sd )
{
struct mapping *mapping;
int access = 0;
+ int unix_fd;
+ struct stat st;
if (!page_mask) init_page_size();
@@ -464,24 +430,26 @@ static struct object *create_mapping( struct directory *root, const struct unico
}
if (!(mapping->file = get_file_obj( current->process, handle, access ))) goto error;
mapping->fd = get_obj_fd( (struct object *)mapping->file );
+ if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error;
if (protect & VPROT_IMAGE)
{
- if (!get_image_params( mapping )) goto error;
+ if (!get_image_params( mapping, unix_fd )) goto error;
return &mapping->obj;
}
+ if (fstat( unix_fd, &st ) == -1)
+ {
+ file_set_error();
+ goto error;
+ }
if (!size)
{
- if (!get_file_size( mapping->file, &size )) goto error;
- if (!size)
+ if (!(size = st.st_size))
{
set_error( STATUS_MAPPED_FILE_SIZE_ZERO );
goto error;
}
}
- else
- {
- if (!grow_file( mapping->file, size )) goto error;
- }
+ else if (st.st_size < size && !grow_file( unix_fd, size )) goto error;
}
else /* Anonymous mapping (no associated file) */
{
@@ -498,7 +466,8 @@ static struct object *create_mapping( struct directory *root, const struct unico
}
if (!(mapping->file = create_temp_file( access ))) goto error;
mapping->fd = get_obj_fd( (struct object *)mapping->file );
- if (!grow_file( mapping->file, size )) goto error;
+ if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error;
+ if (!grow_file( unix_fd, size )) goto error;
}
mapping->size = (size + page_mask) & ~((mem_size_t)page_mask);
mapping->protect = protect;
More information about the wine-cvs
mailing list