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