Commit 3b30002a authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

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

parent 5ede16eb
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment