CVS: winex/dlls/kernel iocompport.c, NONE, 1.1 kernel32.spec, 1.30, 1.31 Makefile.in, 1.4, 1.5

[email protected] 31 Jul 2007 17:57:53 -0000
Newsgroups gmane.comp.emulators.winex.cvs
Message-ID <[email protected]>
Subject: winex/dlls/kernel iocompport.c,NONE,1.1 kernel32.spec,1.30,1.31 Makefile.in,1.4,1.5Update of /var/lib/cvsd/cvsroot/winex/dlls/kernel
In directory agravaine:/tmp/cvs-serv23962/dlls/kernel

Modified Files:
	kernel32.spec Makefile.in 
Added Files:
	iocompport.c 
Log Message:

Partially implement IO completion ports to the point that they can be used as task queues (ie, not associated with a file handle). Still to be done:
- finish thread accounting for blocking
- implement associating a file handle with an IO completion port
- modify relevant functions to send notifications to an associated IO completion port
- lots of testing of corner cases



--- NEW FILE: iocompport.c ---
/*
 * Copyright 2007, TransGaming Technologies Inc.
 *
 * Main reference:
 *   http://www.microsoft.com/technet/sysinternals/information/IoCompletionPorts.mspx
 */

#include "config.h"

#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(iocomp);


/******************************************************************************
 *		CreateIoCompletionPort (KERNEL32.@)
 */
HANDLE WINAPI CreateIoCompletionPort
(HANDLE hFileHandle, HANDLE hExistingCompletionPort, ULONG_PTR dwCompletionKey,
 DWORD dwNumberOfConcurrentThreads)
{
   TRACE ("(0x%x, 0x%x, %lu, %lu)\n", hFileHandle,
          hExistingCompletionPort, dwCompletionKey,
          dwNumberOfConcurrentThreads);

   /* If given a completion port, must also be given a file handle with
      which we are to associate it */
   if ((hExistingCompletionPort != (HANDLE)NULL) &&
       (hFileHandle == INVALID_HANDLE_VALUE))
   {
      SetLastError (ERROR_INVALID_PARAMETER);
      return (HANDLE)NULL;
   }

   if (hFileHandle != INVALID_HANDLE_VALUE)
   {
      FIXME ("Attaching a completion port to a file handle is unimplemented\n");
      SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
      return (HANDLE)NULL;
   }

   /* FIXME - this should probably be done in NtCreateIoCompletion();
      however, we don't currently have easy access to the needed info
      in ntdll */
   if (!dwNumberOfConcurrentThreads)
   {
      SYSTEM_INFO si;

      GetSystemInfo (&si);
      dwNumberOfConcurrentThreads = si.dwNumberOfProcessors;
   }

   /* If not given a completion port, we must create one */
   if (hExistingCompletionPort == (HANDLE)NULL)
   {
      NTSTATUS Ret;
      HANDLE hNewPort;

      Ret = NtCreateIoCompletion (&hNewPort, IO_COMPLETION_ALL_ACCESS,
                                  NULL, dwNumberOfConcurrentThreads);
      if (Ret)
      {
         SetLastError (RtlNtStatusToDosError (Ret));
         return (HANDLE)NULL;
      }

      hExistingCompletionPort = hNewPort;
   }

   return hExistingCompletionPort;
}


/******************************************************************************
 *		GetQueuedCompletionStatus (KERNEL32.@)
 */
BOOL WINAPI GetQueuedCompletionStatus
(HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred,
 PULONG_PTR lpCompletionKey, LPOVERLAPPED *lplpOverlapped,
 DWORD dwMilliseconds)
{
   IO_STATUS_BLOCK StatusBlock;
   NTSTATUS Ret;

   TRACE ("(%x, %p, %p, %p, %ld)\n", CompletionPort,
          lpNumberOfBytesTransferred, lpCompletionKey, lplpOverlapped,
          dwMilliseconds);

   if (!lpNumberOfBytesTransferred)
   {
      SetLastError (ERROR_INVALID_PARAMETER);
      return FALSE;
   }

   if (dwMilliseconds == INFINITE)
      Ret = NtRemoveIoCompletion (CompletionPort, lpCompletionKey,
                                  lplpOverlapped, &StatusBlock, NULL);
   else
   {
      LARGE_INTEGER WaitTime;

      WaitTime.QuadPart = (LONGLONG)dwMilliseconds * 1000;
      Ret = NtRemoveIoCompletion (CompletionPort, lpCompletionKey,
                                  lplpOverlapped, &StatusBlock, &WaitTime);
   }

   if (Ret)
   {
      SetLastError (RtlNtStatusToDosError (Ret));
      return FALSE;
   }

   *lpNumberOfBytesTransferred = StatusBlock.Information;
   return TRUE;
}


/******************************************************************************
 *		PostQueuedCompletionStatus (KERNEL32.@)
 */
BOOL WINAPI PostQueuedCompletionStatus
(HANDLE CompletionPort, DWORD dwNumberOfBytesTransferred,
 ULONG_PTR pCompletionKey, LPOVERLAPPED lpOverlapped)
{
   NTSTATUS Ret;

   TRACE ("(%x, %lu, %lu, %p)\n", CompletionPort,
          dwNumberOfBytesTransferred, pCompletionKey, lpOverlapped);

   Ret = NtSetIoCompletion (CompletionPort, pCompletionKey, lpOverlapped,
                            0, dwNumberOfBytesTransferred);
   if (Ret)
   {
      SetLastError (RtlNtStatusToDosError (Ret));
      return FALSE;
   }

   return TRUE;
}

Index: kernel32.spec
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/kernel/kernel32.spec,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- kernel32.spec	30 Mar 2007 21:19:03 -0000	1.30
+++ kernel32.spec	31 Jul 2007 17:57:51 -0000	1.31
@@ -5,8 +5,8 @@
 
 import  ntdll.dll
 
-debug_channels (comm console debugstr dll int resource stress thunk toolhelp
-                win32)
+debug_channels (comm console debugstr dll int iocomp resource stress
+                thunk toolhelp win32)
 
 # Functions exported by the Win95 kernel32.dll 
 # (these need to have these exact ordinals, for some win95 dlls 

Index: Makefile.in
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/kernel/Makefile.in,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Makefile.in	30 Mar 2007 20:19:59 -0000	1.4
+++ Makefile.in	31 Jul 2007 17:57:51 -0000	1.5
@@ -13,6 +13,8 @@
 	console.c \
 	debugger.c \
 	format_msg.c \
+	isolated.c \
+	iocompport.c \
 	kernel_main.c \
 	pointers.c \
 	stress.c \
@@ -24,8 +26,7 @@
 	utthunk.c \
 	win87em.c \
 	windebug.c \
-	wowthunk.c \
-	isolated.c
+	wowthunk.c
 
 RC_SRCS = \
 	kernel.rc