Alexandre Julliard : ntdll: Simplify wine_server_handle_to_fd.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Nov 1 07:08:58 CST 2006
Module: wine
Branch: master
Commit: 226a14a48308f2a2a78104b8503404bba3f10522
URL: http://source.winehq.org/git/wine.git/?a=commit;h=226a14a48308f2a2a78104b8503404bba3f10522
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Nov 1 13:27:18 2006 +0100
ntdll: Simplify wine_server_handle_to_fd.
Now that we have a critical section, races are no longer possible.
---
dlls/ntdll/server.c | 105 +++++++++++++++++++++++---------------------------
1 files changed, 48 insertions(+), 57 deletions(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index a128930..7df8e02 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -493,76 +493,67 @@ int wine_server_handle_to_fd( obj_handle
RtlEnterCriticalSection( &fd_cache_section );
*unix_fd = -1;
- for (;;)
+
+ SERVER_START_REQ( get_handle_fd )
{
- SERVER_START_REQ( get_handle_fd )
+ req->handle = handle;
+ req->access = access;
+ if (!(ret = wine_server_call( req )))
{
- req->handle = handle;
- req->access = access;
- if (!(ret = wine_server_call( req )))
- {
- fd = reply->fd;
- removable = reply->removable;
- if (flags) *flags = reply->flags;
- }
+ fd = reply->fd;
+ removable = reply->removable;
+ if (flags) *flags = reply->flags;
}
- SERVER_END_REQ;
- if (ret) break;
+ }
+ SERVER_END_REQ;
+ if (ret) goto done;
- if (fd != -1)
- {
- if ((fd = dup(fd)) == -1) ret = FILE_GetNtStatus();
- break;
- }
+ if (fd != -1)
+ {
+ if ((fd = dup(fd)) == -1) ret = FILE_GetNtStatus();
+ goto done;
+ }
- /* 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;
- break;
- }
- if (fd_handle != handle) removable = -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 );
- if (removable == -1)
- {
- FILE_FS_DEVICE_INFORMATION info;
- if (FILE_GetDeviceInfo( fd, &info ) == STATUS_SUCCESS)
- removable = (info.Characteristics & FILE_REMOVABLE_MEDIA) != 0;
- }
- else if (removable) break; /* don't cache it */
+ if (removable == -1)
+ {
+ FILE_FS_DEVICE_INFORMATION info;
+ if (FILE_GetDeviceInfo( fd, &info ) == STATUS_SUCCESS)
+ removable = (info.Characteristics & FILE_REMOVABLE_MEDIA) != 0;
+ }
+ else if (removable) goto done; /* don't cache it */
- /* and store it back into the cache */
- SERVER_START_REQ( set_handle_fd )
+ /* and store it back into the cache */
+ SERVER_START_REQ( set_handle_fd )
+ {
+ req->handle = fd_handle;
+ req->fd = fd;
+ req->removable = removable;
+ if (!(ret = wine_server_call( req )))
{
- req->handle = fd_handle;
- req->fd = fd;
- req->removable = removable;
- if (!(ret = wine_server_call( req )))
+ if (reply->cur_fd != -1) /* it has been cached */
{
- if (reply->cur_fd != -1) /* it has been cached */
- {
- if (reply->cur_fd != fd) close( fd ); /* someone was here before us */
- if ((fd = dup(reply->cur_fd)) == -1) ret = FILE_GetNtStatus();
- }
- }
- else
- {
- close( fd );
- fd = -1;
+ if (reply->cur_fd != fd) close( fd ); /* someone was here before us */
+ if ((fd = dup(reply->cur_fd)) == -1) ret = FILE_GetNtStatus();
}
}
- SERVER_END_REQ;
- if (ret) break;
-
- if (fd_handle == handle) break;
- /* if we received a different handle this means there was
- * a race with another thread; we restart everything from
- * scratch in this case.
- */
- close( fd );
+ else
+ {
+ close( fd );
+ fd = -1;
+ }
}
+ SERVER_END_REQ;
+done:
RtlLeaveCriticalSection( &fd_cache_section );
if (!ret) *unix_fd = fd;
return ret;
More information about the wine-cvs
mailing list