ntdll: Store the fd type in the cache and return it in server_get_unix_fd.
This commit is contained in:
parent
8930427b21
commit
83ce958793
|
@ -2022,7 +2022,7 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
|
|||
|
||||
piosb->Information = 0;
|
||||
|
||||
if ((status = server_get_unix_fd( hDevice, 0, &fd, &needs_close, NULL ))) goto error;
|
||||
if ((status = server_get_unix_fd( hDevice, 0, &fd, &needs_close, NULL, NULL ))) goto error;
|
||||
if ((status = CDROM_Open(fd, &dev)))
|
||||
{
|
||||
if (needs_close) close( fd );
|
||||
|
|
|
@ -1408,7 +1408,7 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
|
|||
return io->u.Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((io->u.Status = server_get_unix_fd( handle, FILE_LIST_DIRECTORY, &fd, &needs_close, NULL )) != STATUS_SUCCESS)
|
||||
if ((io->u.Status = server_get_unix_fd( handle, FILE_LIST_DIRECTORY, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS)
|
||||
return io->u.Status;
|
||||
|
||||
io->Information = 0;
|
||||
|
@ -1935,7 +1935,7 @@ NTSTATUS DIR_unmount_device( HANDLE handle )
|
|||
SERVER_END_REQ;
|
||||
if (status) return status;
|
||||
|
||||
if (!(status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL )))
|
||||
if (!(status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL, NULL )))
|
||||
{
|
||||
struct stat st;
|
||||
char *mount_point = NULL;
|
||||
|
@ -2017,7 +2017,7 @@ NTSTATUS DIR_get_unix_cwd( char **cwd )
|
|||
if (status != STATUS_SUCCESS) goto done;
|
||||
}
|
||||
|
||||
if ((status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL )) == STATUS_SUCCESS)
|
||||
if ((status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL, NULL )) == STATUS_SUCCESS)
|
||||
{
|
||||
RtlEnterCriticalSection( &dir_section );
|
||||
|
||||
|
|
|
@ -396,7 +396,8 @@ static void WINAPI FILE_AsyncReadService(void *user, PIO_STATUS_BLOCK iosb, ULON
|
|||
case STATUS_ALERTED: /* got some new data */
|
||||
if (iosb->u.Status != STATUS_PENDING) FIXME("unexpected status %08x\n", iosb->u.Status);
|
||||
/* check to see if the data is ready (non-blocking) */
|
||||
if ((iosb->u.Status = server_get_unix_fd( fileio->handle, FILE_READ_DATA, &fd, &needs_close, NULL )))
|
||||
if ((iosb->u.Status = server_get_unix_fd( fileio->handle, FILE_READ_DATA, &fd,
|
||||
&needs_close, NULL, NULL )))
|
||||
{
|
||||
fileio_terminate(fileio, iosb);
|
||||
break;
|
||||
|
@ -494,7 +495,8 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
|||
if (!io_status) return STATUS_ACCESS_VIOLATION;
|
||||
|
||||
io_status->Information = 0;
|
||||
io_status->u.Status = server_get_unix_fd( hFile, FILE_READ_DATA, &unix_handle, &needs_close, &flags );
|
||||
io_status->u.Status = server_get_unix_fd( hFile, FILE_READ_DATA, &unix_handle,
|
||||
&needs_close, NULL, &flags );
|
||||
if (io_status->u.Status) return io_status->u.Status;
|
||||
|
||||
if (flags & FD_FLAG_RECV_SHUTDOWN)
|
||||
|
@ -637,7 +639,8 @@ static void WINAPI FILE_AsyncWriteService(void *ovp, IO_STATUS_BLOCK *iosb, ULON
|
|||
{
|
||||
case STATUS_ALERTED:
|
||||
/* write some data (non-blocking) */
|
||||
if ((iosb->u.Status = server_get_unix_fd( fileio->handle, FILE_WRITE_DATA, &fd, &needs_close, NULL )))
|
||||
if ((iosb->u.Status = server_get_unix_fd( fileio->handle, FILE_WRITE_DATA, &fd,
|
||||
&needs_close, NULL, NULL )))
|
||||
{
|
||||
fileio_terminate(fileio, iosb);
|
||||
break;
|
||||
|
@ -713,7 +716,8 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
|||
if (!io_status) return STATUS_ACCESS_VIOLATION;
|
||||
|
||||
io_status->Information = 0;
|
||||
io_status->u.Status = server_get_unix_fd( hFile, FILE_WRITE_DATA, &unix_handle, &needs_close, &flags );
|
||||
io_status->u.Status = server_get_unix_fd( hFile, FILE_WRITE_DATA, &unix_handle,
|
||||
&needs_close, NULL, &flags );
|
||||
if (io_status->u.Status) return io_status->u.Status;
|
||||
|
||||
if (flags & FD_FLAG_SEND_SHUTDOWN)
|
||||
|
@ -1028,7 +1032,8 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
|
|||
break;
|
||||
}
|
||||
|
||||
if ((io->u.Status = server_get_unix_fd( handle, FILE_READ_DATA, &fd, &needs_close, &flags )))
|
||||
if ((io->u.Status = server_get_unix_fd( handle, FILE_READ_DATA, &fd,
|
||||
&needs_close, NULL, &flags )))
|
||||
break;
|
||||
|
||||
if (flags & FD_FLAG_RECV_SHUTDOWN)
|
||||
|
@ -1217,7 +1222,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
|||
|
||||
if (class != FilePipeLocalInformation)
|
||||
{
|
||||
if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL )))
|
||||
if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, NULL )))
|
||||
return io->u.Status;
|
||||
}
|
||||
|
||||
|
@ -1366,7 +1371,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
|||
if (tmpbuf)
|
||||
{
|
||||
int fd, needs_close;
|
||||
if (!server_get_unix_fd( hFile, FILE_READ_DATA, &fd, &needs_close, NULL ))
|
||||
if (!server_get_unix_fd( hFile, FILE_READ_DATA, &fd, &needs_close, NULL, NULL ))
|
||||
{
|
||||
int res = recv( fd, tmpbuf, size, MSG_PEEK );
|
||||
info->MessagesAvailable = (res > 0);
|
||||
|
@ -1438,7 +1443,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
|||
|
||||
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", handle, io, ptr, len, class);
|
||||
|
||||
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL )))
|
||||
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
|
||||
return io->u.Status;
|
||||
|
||||
io->u.Status = STATUS_SUCCESS;
|
||||
|
@ -1827,7 +1832,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io
|
|||
int fd, needs_close;
|
||||
struct stat st;
|
||||
|
||||
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL )) != STATUS_SUCCESS)
|
||||
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS)
|
||||
return io->u.Status;
|
||||
|
||||
io->u.Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -63,7 +63,7 @@ extern void DECLSPEC_NORETURN server_exit_thread( int status );
|
|||
extern void DECLSPEC_NORETURN server_abort_thread( int status );
|
||||
extern int server_remove_fd_from_cache( obj_handle_t handle );
|
||||
extern int server_get_unix_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
|
||||
int *flags, int *needs_close );
|
||||
int *needs_close, enum server_fd_type *type, int *flags );
|
||||
|
||||
/* module handling */
|
||||
extern NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved );
|
||||
|
|
|
@ -982,7 +982,7 @@ static DWORD CALLBACK wait_for_event(LPVOID arg)
|
|||
async_commio *commio = (async_commio*) arg;
|
||||
int fd, needs_close;
|
||||
|
||||
if (!server_get_unix_fd( commio->hDevice, FILE_READ_DATA | FILE_WRITE_DATA, &fd, &needs_close, NULL ))
|
||||
if (!server_get_unix_fd( commio->hDevice, FILE_READ_DATA | FILE_WRITE_DATA, &fd, &needs_close, NULL, NULL ))
|
||||
{
|
||||
serial_irq_info new_irq_info;
|
||||
DWORD new_mstat, new_evtmask;
|
||||
|
@ -1130,7 +1130,7 @@ static inline NTSTATUS io_control(HANDLE hDevice,
|
|||
piosb->Information = 0;
|
||||
|
||||
if (dwIoControlCode != IOCTL_SERIAL_GET_TIMEOUTS)
|
||||
if ((status = server_get_unix_fd( hDevice, access, &fd, &needs_close, NULL )))
|
||||
if ((status = server_get_unix_fd( hDevice, access, &fd, &needs_close, NULL, NULL )))
|
||||
goto error;
|
||||
|
||||
switch (dwIoControlCode)
|
||||
|
|
|
@ -443,7 +443,13 @@ inline static unsigned int handle_to_index( obj_handle_t handle )
|
|||
return ((unsigned long)handle >> 2) - 1;
|
||||
}
|
||||
|
||||
static int *fd_cache;
|
||||
struct fd_cache_entry
|
||||
{
|
||||
int fd;
|
||||
enum server_fd_type type;
|
||||
};
|
||||
|
||||
static struct fd_cache_entry *fd_cache;
|
||||
static unsigned int fd_cache_size;
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -451,14 +457,14 @@ static unsigned int fd_cache_size;
|
|||
*
|
||||
* Caller must hold fd_cache_section.
|
||||
*/
|
||||
static int add_fd_to_cache( obj_handle_t handle, int fd )
|
||||
static int add_fd_to_cache( obj_handle_t handle, int fd, enum server_fd_type type )
|
||||
{
|
||||
unsigned int idx = handle_to_index( handle );
|
||||
|
||||
if (idx >= fd_cache_size)
|
||||
{
|
||||
unsigned int i, size = max( 32, fd_cache_size * 2 );
|
||||
int *new_cache;
|
||||
struct fd_cache_entry *new_cache;
|
||||
|
||||
if (size <= idx) size = idx + 1;
|
||||
if (fd_cache)
|
||||
|
@ -468,16 +474,17 @@ static int add_fd_to_cache( obj_handle_t handle, int fd )
|
|||
|
||||
if (new_cache)
|
||||
{
|
||||
for (i = fd_cache_size; i < size; i++) new_cache[i] = -1;
|
||||
for (i = fd_cache_size; i < size; i++) new_cache[i].fd = -1;
|
||||
fd_cache = new_cache;
|
||||
fd_cache_size = size;
|
||||
}
|
||||
}
|
||||
if (idx < fd_cache_size)
|
||||
{
|
||||
assert( fd_cache[idx] == -1 );
|
||||
fd_cache[idx] = fd;
|
||||
TRACE("added %p (%d) to cache\n", handle, fd );
|
||||
assert( fd_cache[idx].fd == -1 );
|
||||
fd_cache[idx].fd = fd;
|
||||
fd_cache[idx].type = type;
|
||||
TRACE("added %p (%d) type %d to cache\n", handle, fd, type );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -489,12 +496,16 @@ static int add_fd_to_cache( obj_handle_t handle, int fd )
|
|||
*
|
||||
* Caller must hold fd_cache_section.
|
||||
*/
|
||||
static inline int get_cached_fd( obj_handle_t handle )
|
||||
static inline int get_cached_fd( obj_handle_t handle, enum server_fd_type *type )
|
||||
{
|
||||
unsigned int idx = handle_to_index( handle );
|
||||
int fd = -1;
|
||||
|
||||
if (idx < fd_cache_size) fd = fd_cache[idx];
|
||||
if (idx < fd_cache_size)
|
||||
{
|
||||
fd = fd_cache[idx].fd;
|
||||
if (type) *type = fd_cache[idx].type;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -510,8 +521,8 @@ int server_remove_fd_from_cache( obj_handle_t handle )
|
|||
RtlEnterCriticalSection( &fd_cache_section );
|
||||
if (idx < fd_cache_size)
|
||||
{
|
||||
fd = fd_cache[idx];
|
||||
fd_cache[idx] = -1;
|
||||
fd = fd_cache[idx].fd;
|
||||
fd_cache[idx].fd = -1;
|
||||
}
|
||||
RtlLeaveCriticalSection( &fd_cache_section );
|
||||
|
||||
|
@ -530,7 +541,7 @@ int server_remove_fd_from_cache( obj_handle_t handle )
|
|||
* The returned unix_fd should be closed iff needs_close is non-zero.
|
||||
*/
|
||||
int server_get_unix_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
|
||||
int *needs_close, int *flags )
|
||||
int *needs_close, enum server_fd_type *type, int *flags )
|
||||
{
|
||||
obj_handle_t fd_handle;
|
||||
int ret = 0, removable = 0, fd;
|
||||
|
@ -540,7 +551,7 @@ int server_get_unix_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
|
|||
|
||||
RtlEnterCriticalSection( &fd_cache_section );
|
||||
|
||||
fd = get_cached_fd( handle );
|
||||
fd = get_cached_fd( handle, type );
|
||||
if (fd != -1 && !flags) goto done;
|
||||
|
||||
SERVER_START_REQ( get_handle_fd )
|
||||
|
@ -551,24 +562,21 @@ int server_get_unix_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
|
|||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
removable = reply->flags & FD_FLAG_REMOVABLE;
|
||||
if (type) *type = reply->type;
|
||||
if (flags) *flags = reply->flags;
|
||||
if (fd == -1)
|
||||
{
|
||||
if ((fd = receive_fd( &fd_handle )) != -1)
|
||||
{
|
||||
assert( fd_handle == handle );
|
||||
if (!removable) add_fd_to_cache( handle, fd, reply->type );
|
||||
}
|
||||
else ret = STATUS_TOO_MANY_OPENED_FILES;
|
||||
}
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!ret && fd == -1)
|
||||
{
|
||||
/* it wasn't in the cache, get it from the server */
|
||||
fd = receive_fd( &fd_handle );
|
||||
if (fd == -1)
|
||||
{
|
||||
ret = STATUS_TOO_MANY_OPENED_FILES;
|
||||
goto done;
|
||||
}
|
||||
assert( fd_handle == handle );
|
||||
*needs_close = removable || !add_fd_to_cache( handle, fd );
|
||||
}
|
||||
|
||||
done:
|
||||
RtlLeaveCriticalSection( &fd_cache_section );
|
||||
if (!ret) *unix_fd = fd;
|
||||
|
@ -625,7 +633,7 @@ int wine_server_fd_to_handle( int fd, unsigned int access, unsigned int attribut
|
|||
*/
|
||||
int wine_server_handle_to_fd( obj_handle_t handle, unsigned int access, int *unix_fd, int *flags )
|
||||
{
|
||||
int needs_close, ret = server_get_unix_fd( handle, access, unix_fd, &needs_close, flags );
|
||||
int needs_close, ret = server_get_unix_fd( handle, access, unix_fd, &needs_close, NULL, flags );
|
||||
|
||||
if (!ret && !needs_close)
|
||||
{
|
||||
|
|
|
@ -524,7 +524,7 @@ NTSTATUS TAPE_DeviceIoControl( HANDLE device, HANDLE event,
|
|||
|
||||
io_status->Information = 0;
|
||||
|
||||
if ((status = server_get_unix_fd( device, 0, &fd, &needs_close, NULL )))
|
||||
if ((status = server_get_unix_fd( device, 0, &fd, &needs_close, NULL, NULL )))
|
||||
goto error;
|
||||
|
||||
switch (io_control)
|
||||
|
|
|
@ -1810,7 +1810,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
SERVER_END_REQ;
|
||||
if (res) return res;
|
||||
|
||||
if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, &flags ))) return res;
|
||||
if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, &flags ))) return res;
|
||||
removable = (flags & FD_FLAG_REMOVABLE) != 0;
|
||||
|
||||
if (prot & VPROT_IMAGE)
|
||||
|
@ -1820,7 +1820,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
int shared_fd, shared_needs_close;
|
||||
|
||||
if ((res = server_get_unix_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA,
|
||||
&shared_fd, &shared_needs_close, NULL ))) goto done;
|
||||
&shared_fd, &shared_needs_close, NULL, NULL ))) goto done;
|
||||
res = map_image( handle, unix_handle, base, size_low, mask, header_size,
|
||||
shared_fd, removable, addr_ptr );
|
||||
if (shared_needs_close) close( shared_fd );
|
||||
|
|
Loading…
Reference in New Issue