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; 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 ((status = CDROM_Open(fd, &dev)))
{ {
if (needs_close) close( fd ); 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; 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; return io->u.Status;
io->Information = 0; io->Information = 0;
@ -1935,7 +1935,7 @@ NTSTATUS DIR_unmount_device( HANDLE handle )
SERVER_END_REQ; SERVER_END_REQ;
if (status) return status; 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; struct stat st;
char *mount_point = NULL; char *mount_point = NULL;
@ -2017,7 +2017,7 @@ NTSTATUS DIR_get_unix_cwd( char **cwd )
if (status != STATUS_SUCCESS) goto done; 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 ); 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 */ case STATUS_ALERTED: /* got some new data */
if (iosb->u.Status != STATUS_PENDING) FIXME("unexpected status %08x\n", iosb->u.Status); if (iosb->u.Status != STATUS_PENDING) FIXME("unexpected status %08x\n", iosb->u.Status);
/* check to see if the data is ready (non-blocking) */ /* 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); fileio_terminate(fileio, iosb);
break; break;
@ -494,7 +495,8 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
if (!io_status) return STATUS_ACCESS_VIOLATION; if (!io_status) return STATUS_ACCESS_VIOLATION;
io_status->Information = 0; 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 (io_status->u.Status) return io_status->u.Status;
if (flags & FD_FLAG_RECV_SHUTDOWN) 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: case STATUS_ALERTED:
/* write some data (non-blocking) */ /* 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); fileio_terminate(fileio, iosb);
break; break;
@ -713,7 +716,8 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
if (!io_status) return STATUS_ACCESS_VIOLATION; if (!io_status) return STATUS_ACCESS_VIOLATION;
io_status->Information = 0; 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 (io_status->u.Status) return io_status->u.Status;
if (flags & FD_FLAG_SEND_SHUTDOWN) if (flags & FD_FLAG_SEND_SHUTDOWN)
@ -1028,7 +1032,8 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
break; 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; break;
if (flags & FD_FLAG_RECV_SHUTDOWN) if (flags & FD_FLAG_RECV_SHUTDOWN)
@ -1217,7 +1222,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (class != FilePipeLocalInformation) 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; return io->u.Status;
} }
@ -1366,7 +1371,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (tmpbuf) if (tmpbuf)
{ {
int fd, needs_close; 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 ); int res = recv( fd, tmpbuf, size, MSG_PEEK );
info->MessagesAvailable = (res > 0); 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); 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; return io->u.Status;
io->u.Status = STATUS_SUCCESS; io->u.Status = STATUS_SUCCESS;
@ -1827,7 +1832,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io
int fd, needs_close; int fd, needs_close;
struct stat st; 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; return io->u.Status;
io->u.Status = STATUS_NOT_IMPLEMENTED; 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 void DECLSPEC_NORETURN server_abort_thread( int status );
extern int server_remove_fd_from_cache( obj_handle_t handle ); 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, 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 */ /* module handling */
extern NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved ); 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; async_commio *commio = (async_commio*) arg;
int fd, needs_close; 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; serial_irq_info new_irq_info;
DWORD new_mstat, new_evtmask; DWORD new_mstat, new_evtmask;
@ -1130,7 +1130,7 @@ static inline NTSTATUS io_control(HANDLE hDevice,
piosb->Information = 0; piosb->Information = 0;
if (dwIoControlCode != IOCTL_SERIAL_GET_TIMEOUTS) 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; goto error;
switch (dwIoControlCode) 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; 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; static unsigned int fd_cache_size;
/*********************************************************************** /***********************************************************************
@ -451,14 +457,14 @@ static unsigned int fd_cache_size;
* *
* Caller must hold fd_cache_section. * 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 ); unsigned int idx = handle_to_index( handle );
if (idx >= fd_cache_size) if (idx >= fd_cache_size)
{ {
unsigned int i, size = max( 32, fd_cache_size * 2 ); 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 (size <= idx) size = idx + 1;
if (fd_cache) if (fd_cache)
@ -468,16 +474,17 @@ static int add_fd_to_cache( obj_handle_t handle, int fd )
if (new_cache) 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 = new_cache;
fd_cache_size = size; fd_cache_size = size;
} }
} }
if (idx < fd_cache_size) if (idx < fd_cache_size)
{ {
assert( fd_cache[idx] == -1 ); assert( fd_cache[idx].fd == -1 );
fd_cache[idx] = fd; fd_cache[idx].fd = fd;
TRACE("added %p (%d) to cache\n", handle, fd ); fd_cache[idx].type = type;
TRACE("added %p (%d) type %d to cache\n", handle, fd, type );
return 1; return 1;
} }
return 0; return 0;
@ -489,12 +496,16 @@ static int add_fd_to_cache( obj_handle_t handle, int fd )
* *
* Caller must hold fd_cache_section. * 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 ); unsigned int idx = handle_to_index( handle );
int fd = -1; 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; return fd;
} }
@ -510,8 +521,8 @@ int server_remove_fd_from_cache( obj_handle_t handle )
RtlEnterCriticalSection( &fd_cache_section ); RtlEnterCriticalSection( &fd_cache_section );
if (idx < fd_cache_size) if (idx < fd_cache_size)
{ {
fd = fd_cache[idx]; fd = fd_cache[idx].fd;
fd_cache[idx] = -1; fd_cache[idx].fd = -1;
} }
RtlLeaveCriticalSection( &fd_cache_section ); 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. * 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 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; obj_handle_t fd_handle;
int ret = 0, removable = 0, fd; 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 ); RtlEnterCriticalSection( &fd_cache_section );
fd = get_cached_fd( handle ); fd = get_cached_fd( handle, type );
if (fd != -1 && !flags) goto done; if (fd != -1 && !flags) goto done;
SERVER_START_REQ( get_handle_fd ) 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 ))) if (!(ret = wine_server_call( req )))
{ {
removable = reply->flags & FD_FLAG_REMOVABLE; removable = reply->flags & FD_FLAG_REMOVABLE;
if (type) *type = reply->type;
if (flags) *flags = reply->flags; 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; 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: done:
RtlLeaveCriticalSection( &fd_cache_section ); RtlLeaveCriticalSection( &fd_cache_section );
if (!ret) *unix_fd = fd; 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 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) if (!ret && !needs_close)
{ {

View File

@ -524,7 +524,7 @@ NTSTATUS TAPE_DeviceIoControl( HANDLE device, HANDLE event,
io_status->Information = 0; 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; goto error;
switch (io_control) switch (io_control)

View File

@ -1810,7 +1810,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
SERVER_END_REQ; SERVER_END_REQ;
if (res) return res; 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; removable = (flags & FD_FLAG_REMOVABLE) != 0;
if (prot & VPROT_IMAGE) if (prot & VPROT_IMAGE)
@ -1820,7 +1820,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
int shared_fd, shared_needs_close; int shared_fd, shared_needs_close;
if ((res = server_get_unix_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA, 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, res = map_image( handle, unix_handle, base, size_low, mask, header_size,
shared_fd, removable, addr_ptr ); shared_fd, removable, addr_ptr );
if (shared_needs_close) close( shared_fd ); if (shared_needs_close) close( shared_fd );