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