ntdll: Store the fd type in the cache and return it in server_get_unix_fd.

This commit is contained in:
Alexandre Julliard 2006-11-20 14:15:06 +01:00
parent 8930427b21
commit 83ce958793
8 changed files with 59 additions and 46 deletions

View File

@ -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 );

View File

@ -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 );

View File

@ -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;

View File

@ -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 );

View File

@ -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)

View File

@ -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)
{

View File

@ -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)

View File

@ -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 );