File record locking (exclusive, nowait)
Medland, Bill
Bill.Medland at accpac.com
Wed Nov 7 16:50:45 CST 2001
<<diff29.txt>>
-------------- next part --------------
Bill Medland (medbi01 at accpac.com)
Basic file locking implementation (exclusive, nowait only) based on
the code from the corelwine tree.
Index: wine/server/Makefile.in
===================================================================
RCS file: /home/wine/wine/server/Makefile.in,v
retrieving revision 1.30
diff -u -r1.30 Makefile.in
--- wine/server/Makefile.in 2001/08/28 18:44:53 1.30
+++ wine/server/Makefile.in 2001/11/07 21:23:25
@@ -15,6 +15,7 @@
debugger.c \
device.c \
event.c \
+ fd.c \
file.c \
handle.c \
main.c \
Index: wine/server/file.c
===================================================================
RCS file: /home/wine/wine/server/file.c,v
retrieving revision 1.48
diff -u -r1.48 file.c
--- wine/server/file.c 2001/10/24 00:23:26 1.48
+++ wine/server/file.c 2001/11/07 21:23:25
@@ -27,12 +27,14 @@
#include "winbase.h"
#include "handle.h"
+#include "file.h"
#include "thread.h"
#include "request.h"
struct file
{
struct object obj; /* object header */
+ struct fd *fd; /* file descriptor */
struct file *next; /* next file in hashing list */
char *name; /* file name */
unsigned int access; /* file access (GENERIC_READ/WRITE) */
@@ -103,14 +105,17 @@
/* create a file from a file descriptor */
/* if the function fails the fd is closed */
-static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing,
+static struct file *create_file_for_fd( struct fd *fd, unsigned int access,
+ unsigned int sharing,
unsigned int attrs, int drive_type )
{
struct file *file;
- if ((file = alloc_object( &file_ops, fd )))
+ assert (fd);
+ if ((file = alloc_object( &file_ops, get_unix_fd(fd) )))
{
file->name = NULL;
file->next = NULL;
+ file->fd = fd;
file->access = access;
file->flags = attrs;
file->sharing = sharing;
@@ -124,11 +129,10 @@
unsigned int sharing, int create, unsigned int attrs,
int drive_type )
{
+ struct fd *fd = NULL;
struct file *file;
int hash, flags;
- struct stat st;
char *name;
- int fd = -1;
mode_t mode;
if (!(name = mem_alloc( len + 1 ))) return NULL;
@@ -162,11 +166,10 @@
mode |= 0111;
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
- if ((fd = open( name, flags | O_NONBLOCK | O_LARGEFILE, mode )) == -1 )
+ if (!(fd = open_fd( name, flags | O_NONBLOCK | O_LARGEFILE, mode )))
goto file_error;
/* refuse to open a directory */
- if (fstat( fd, &st ) == -1) goto file_error;
- if (S_ISDIR(st.st_mode))
+ if (S_ISDIR(get_unix_mode(fd)))
{
set_error( STATUS_ACCESS_DENIED );
goto error;
@@ -185,7 +188,7 @@
file_error:
file_set_error();
error:
- if (fd != -1) close( fd );
+ if (fd) close_fd( fd );
free( name );
return NULL;
}
@@ -229,9 +232,11 @@
/* Create a temp file for anonymous mappings */
struct file *create_temp_file( int access )
{
- int fd;
+ struct fd *fd;
+ int unix_fd;
- if ((fd = create_anonymous_file()) == -1) return NULL;
+ if ((unix_fd = create_anonymous_file()) == -1) return NULL;
+ if (!(fd = create_anonymous_fd( unix_fd ))) return NULL;
return create_file_for_fd( fd, access, 0, 0, DRIVE_FIXED );
}
@@ -239,7 +244,10 @@
{
struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
- fprintf( stderr, "File fd=%d flags=%08x name='%s'\n", file->obj.fd, file->flags, file->name );
+ assert( file->fd );
+ fprintf( stderr, "File fd=%d flags=%08x name='%s'\n",
+ get_unix_fd (file->fd),
+ file->flags, file->name );
}
static int file_get_poll_events( struct object *obj )
@@ -256,7 +264,7 @@
{
struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
- return file->obj.fd;
+ return get_unix_fd(file->fd);
}
static int file_flush( struct object *obj )
@@ -265,7 +273,7 @@
struct file *file = (struct file *)grab_object(obj);
assert( obj->ops == &file_ops );
- ret = (fsync( file->obj.fd ) != -1);
+ ret = (fsync( get_unix_fd( file->fd ) ) != -1);
if (!ret) file_set_error();
release_object( file );
return ret;
@@ -279,7 +287,7 @@
if (req)
{
- if (fstat( file->obj.fd, &st ) == -1)
+ if (fstat( get_unix_fd(file->fd), &st ) == -1)
{
file_set_error();
return FD_TYPE_INVALID;
@@ -325,6 +333,7 @@
if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
free( file->name );
}
+ close_fd (file->fd);
}
/* set the last error depending on errno */
@@ -366,7 +375,7 @@
xto = *low+((off_t)*high<<32);
if (!(file = get_file_obj( current->process, handle, 0 )))
return 0;
- if ((result = lseek(file->obj.fd,xto,whence))==-1)
+ if ((result = lseek (get_unix_fd (file->fd),xto,whence))==-1)
{
/* Check for seek before start of file */
@@ -392,8 +401,8 @@
if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
return 0;
- if (((result = lseek( file->obj.fd, 0, SEEK_CUR )) == -1) ||
- (ftruncate( file->obj.fd, result ) == -1))
+ if (((result = lseek( get_unix_fd(file->fd), 0, SEEK_CUR )) == -1) ||
+ (ftruncate( get_unix_fd(file->fd), result ) == -1))
{
file_set_error();
release_object( file );
@@ -409,13 +418,13 @@
struct stat st;
off_t size = size_low + (((off_t)size_high)<<32);
- if (fstat( file->obj.fd, &st ) == -1)
+ if (fstat( get_unix_fd(file->fd), &st ) == -1)
{
file_set_error();
return 0;
}
if (st.st_size >= size) return 1; /* already large enough */
- if (ftruncate( file->obj.fd, size ) != -1) return 1;
+ if (ftruncate( get_unix_fd(file->fd), size ) != -1) return 1;
file_set_error();
return 0;
}
@@ -451,20 +460,6 @@
return 0;
}
-static int file_lock( struct file *file, int offset_high, int offset_low,
- int count_high, int count_low )
-{
- /* FIXME: implement this */
- return 1;
-}
-
-static int file_unlock( struct file *file, int offset_high, int offset_low,
- int count_high, int count_low )
-{
- /* FIXME: implement this */
- return 1;
-}
-
/* create a file */
DECL_HANDLER(create_file)
{
@@ -483,14 +478,16 @@
DECL_HANDLER(alloc_file_handle)
{
struct file *file;
- int fd;
+ int unix_fd;
+ struct fd *fd;
req->handle = 0;
- if ((fd = thread_get_inflight_fd( current, req->fd )) == -1)
+ if ((unix_fd = thread_get_inflight_fd( current, req->fd )) == -1)
{
set_error( STATUS_INVALID_HANDLE );
return;
}
+ if (!(fd = create_anonymous_fd (unix_fd))) return;
if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE,
0, DRIVE_UNKNOWN )))
{
@@ -571,10 +568,14 @@
{
struct file *file;
+ /* FIXME - The Corel version handles share mode too but beware the
+ * modes.
+ */
if ((file = get_file_obj( current->process, req->handle, 0 )))
{
- file_lock( file, req->offset_high, req->offset_low,
- req->count_high, req->count_low );
+ lock_fd( file->fd, req->offset_high, req->offset_low,
+ req->count_high, req->count_low,
+ 0 /* exclusive */, 0 /* nowait */ );
release_object( file );
}
}
@@ -586,8 +587,8 @@
if ((file = get_file_obj( current->process, req->handle, 0 )))
{
- file_unlock( file, req->offset_high, req->offset_low,
- req->count_high, req->count_low );
+ unlock_fd( file->fd, req->offset_high, req->offset_low,
+ req->count_high, req->count_low );
release_object( file );
}
}
Index: wine/server/object.c
===================================================================
RCS file: /home/wine/wine/server/object.c,v
retrieving revision 1.19
diff -u -r1.19 object.c
--- wine/server/object.c 2001/10/04 16:18:15 1.19
+++ wine/server/object.c 2001/11/07 21:23:25
@@ -257,6 +257,11 @@
return -1;
}
+int default_get_fd( struct object *obj )
+{
+ return obj->fd;
+}
+
int no_flush( struct object *obj )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
@@ -277,7 +282,10 @@
int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry )
{
if (!obj->head) /* first on the queue */
+ {
+ assert (obj->select != -1);
set_select_events( obj, obj->ops->get_poll_events( obj ) );
+ }
add_queue( obj, entry );
return 1;
}
Index: wine/server/object.h
===================================================================
RCS file: /home/wine/wine/server/object.h,v
retrieving revision 1.35
diff -u -r1.35 object.h
--- wine/server/object.h 2001/10/24 00:23:26 1.35
+++ wine/server/object.h 2001/11/07 21:23:25
@@ -88,6 +88,7 @@
extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern int no_satisfied( struct object *obj, struct thread *thread );
extern int no_get_fd( struct object *obj );
+extern int default_get_fd( struct object *obj );
extern int no_flush( struct object *obj );
extern int no_get_file_info( struct object *obj, struct get_file_info_request *info );
extern void no_destroy( struct object *obj );
Index: wine/server/process.c
===================================================================
RCS file: /home/wine/wine/server/process.c,v
retrieving revision 1.71
diff -u -r1.71 process.c
--- wine/server/process.c 2001/10/25 19:52:12 1.71
+++ wine/server/process.c 2001/11/07 21:23:25
@@ -171,6 +171,7 @@
process->exe.next = NULL;
process->exe.prev = NULL;
process->exe.file = NULL;
+ process->locks = NULL;
process->exe.dbg_offset = 0;
process->exe.dbg_size = 0;
gettimeofday( &process->start_time, NULL );
Index: wine/server/process.h
===================================================================
RCS file: /home/wine/wine/server/process.h,v
retrieving revision 1.22
diff -u -r1.22 process.h
--- wine/server/process.h 2001/07/19 00:35:37 1.22
+++ wine/server/process.h 2001/11/07 21:23:25
@@ -25,6 +25,8 @@
int dbg_size; /* debug info size */
};
+struct file_lock;
+
struct process
{
struct object obj; /* object header */
@@ -50,6 +52,7 @@
struct process_dll exe; /* main exe file */
void *ldt_copy; /* pointer to LDT copy in client addr space */
void *ldt_flags; /* pointer to LDT flags in client addr space */
+ struct file_lock *locks; /* Linked list of file locks */
};
struct process_snapshot
Index: wine/server/select.c
===================================================================
RCS file: /home/wine/wine/server/select.c,v
retrieving revision 1.13
diff -u -r1.13 select.c
--- wine/server/select.c 2001/11/06 22:25:11 1.13
+++ wine/server/select.c 2001/11/07 21:23:25
@@ -111,6 +111,7 @@
void set_select_events( struct object *obj, int events )
{
int user = obj->select;
+ assert (user != -1);
assert( poll_users[user] == obj );
if (events == -1) /* stop waiting on this fd completely */
{
More information about the wine-patches
mailing list