Jacek Caban : ntdll: Cache error information for cacheable handles with no fd.

Alexandre Julliard julliard at winehq.org
Fri Oct 28 13:47:07 CDT 2016


Module: wine
Branch: master
Commit: 3b30002aecf7cd55970979f7e02a53866fe66f1f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3b30002aecf7cd55970979f7e02a53866fe66f1f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Oct 24 17:48:49 2016 +0200

ntdll: Cache error information for cacheable handles with no fd.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/server.c | 45 ++++++++++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 25c6473..59b9ab9 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -876,22 +876,25 @@ static BOOL add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
 /***********************************************************************
  *           get_cached_fd
  */
-static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
-                                 unsigned int *access, unsigned int *options )
+static inline NTSTATUS get_cached_fd( HANDLE handle, int *fd, enum server_fd_type *type,
+                                      unsigned int *access, unsigned int *options )
 {
     unsigned int entry, idx = handle_to_index( handle, &entry );
-    int fd = -1;
+    union fd_cache_entry cache;
 
-    if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
-    {
-        union fd_cache_entry cache;
-        cache.data = interlocked_cmpxchg64( &fd_cache[entry][idx].data, 0, 0 );
-        fd = cache.s.fd - 1;
-        if (type) *type = cache.s.type;
-        if (access) *access = cache.s.access;
-        if (options) *options = cache.s.options;
-    }
-    return fd;
+    if (entry >= FD_CACHE_ENTRIES || !fd_cache[entry]) return STATUS_INVALID_HANDLE;
+
+    cache.data = interlocked_cmpxchg64( &fd_cache[entry][idx].data, 0, 0 );
+    if (!cache.data) return STATUS_INVALID_HANDLE;
+
+    /* if fd type is invalid, fd stores an error value */
+    if (cache.s.type == FD_TYPE_INVALID) return cache.s.fd - 1;
+
+    *fd = cache.s.fd - 1;
+    if (type) *type = cache.s.type;
+    if (access) *access = cache.s.access;
+    if (options) *options = cache.s.options;
+    return STATUS_SUCCESS;
 }
 
 
@@ -907,7 +910,7 @@ int server_remove_fd_from_cache( HANDLE handle )
     {
         union fd_cache_entry cache;
         cache.data = interlocked_xchg64( &fd_cache[entry][idx].data, 0 );
-        fd = cache.s.fd - 1;
+        if (cache.s.type != FD_TYPE_INVALID) fd = cache.s.fd - 1;
     }
 
     return fd;
@@ -924,19 +927,19 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
 {
     sigset_t sigset;
     obj_handle_t fd_handle;
-    int ret = 0, fd;
+    int ret, fd = -1;
     unsigned int access = 0;
 
     *unix_fd = -1;
     *needs_close = 0;
     wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA;
 
-    fd = get_cached_fd( handle, type, &access, options );
-    if (fd != -1) goto done;
+    ret = get_cached_fd( handle, &fd, type, &access, options );
+    if (ret != STATUS_INVALID_HANDLE) goto done;
 
     server_enter_uninterrupted_section( &fd_cache_section, &sigset );
-    fd = get_cached_fd( handle, type, &access, options );
-    if (fd == -1)
+    ret = get_cached_fd( handle, &fd, type, &access, options );
+    if (ret == STATUS_INVALID_HANDLE)
     {
         SERVER_START_REQ( get_handle_fd )
         {
@@ -955,6 +958,10 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
                 }
                 else ret = STATUS_TOO_MANY_OPENED_FILES;
             }
+            else if (reply->cacheable)
+            {
+                add_fd_to_cache( handle, ret, FD_TYPE_INVALID, 0, 0 );
+            }
         }
         SERVER_END_REQ;
     }




More information about the wine-cvs mailing list