CVS: winex/dlls/ntdll iocomp.c, NONE, 1.1 Makefile.in, 1.7, 1.8 ntdll.spec, 1.48, 1.49
[email protected] 31 Jul 2007 17:58:52 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/dlls/ntdll iocomp.c,NONE,1.1 Makefile.in,1.7,1.8 ntdll.spec,1.48,1.49Update of /var/lib/cvsd/cvsroot/winex/dlls/ntdll
In directory agravaine:/tmp/cvs-serv24177/dlls/ntdll
Modified Files:
Makefile.in ntdll.spec
Added Files:
iocomp.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: iocomp.c ---
/*
* Copyright 2007, TransGaming Technologies Inc.
*
* Main reference:
* http://www.microsoft.com/technet/sysinternals/information/IoCompletionPorts.mspx
*/
#include "config.h"
#include "winternl.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(iocomp);
/******************************************************************************
* NtCreateIoCompletion (ntdll.@)
*/
NTSTATUS WINAPI NtCreateIoCompletion
(PHANDLE pIoCompletionHandle, ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES pObjectAttributes, ULONG NumberOfConcurrentThreads)
{
NTSTATUS Ret;
TRACE ("(%p, 0x%x, %p, %lu)\n",
pIoCompletionHandle, DesiredAccess, pObjectAttributes,
NumberOfConcurrentThreads);
if (pObjectAttributes)
FIXME ("pObjectAttributes are not supported\n");
if (pIoCompletionHandle == NULL)
return STATUS_INVALID_PARAMETER;
if (NumberOfConcurrentThreads == 0)
{
FIXME ("Need to query number of processors\n");
NumberOfConcurrentThreads = 2;
}
SERVER_START_REQ(create_io_completion)
{
req->num_threads = NumberOfConcurrentThreads;
Ret = wine_server_call (req);
*pIoCompletionHandle = reply->handle;
}
SERVER_END_REQ;
TRACE ("Ret=0x%lx, *pIoCompletionHandle=0x%x\n", Ret,
*pIoCompletionHandle);
return Ret;
}
/******************************************************************************
* NtRemoveIoCompletion (ntdll.@)
*/
NTSTATUS WINAPI NtRemoveIoCompletion
(HANDLE IoCompletionHandle, PULONG_PTR ppCompletionKey,
LPOVERLAPPED *lplpOverlapped, PIO_STATUS_BLOCK pIoStatusBlock,
PLARGE_INTEGER pWaitTime)
{
NTSTATUS Ret;
int cookie;
TRACE ("(0x%x, %p, %p, %p, %p)\n", IoCompletionHandle,
ppCompletionKey, lplpOverlapped, pIoStatusBlock, pWaitTime);
if (!ppCompletionKey || !lplpOverlapped || !pIoStatusBlock)
return STATUS_INVALID_PARAMETER;
/* Ask for a task to do. If one's given to us, run with it. Otherwise,
wait for one to be given to us */
SERVER_START_REQ(remove_io_completion)
{
req->handle = IoCompletionHandle;
req->cookie = &cookie;
if (pWaitTime)
{
req->sec = pWaitTime->QuadPart / 1000000;
req->usec = pWaitTime->QuadPart % 1000000;
req->select_flags = SELECT_TIMEOUT;
}
else
{
req->sec = 0;
req->usec = 0;
req->select_flags = 0;
}
Ret = wine_server_call (req);
pIoStatusBlock->u.Status = Ret;
if (Ret == STATUS_SUCCESS)
{
*ppCompletionKey = (ULONG_PTR)reply->completion_key;
*lplpOverlapped = reply->overlapped;
pIoStatusBlock->Information = reply->num_bytes;
}
}
SERVER_END_REQ;
/* This can timeout immediately if a timeout of 0 is specified and
no tasks are available */
if ((Ret == STATUS_SUCCESS) || (Ret == STATUS_TIMEOUT))
{
TRACE ("Ret=0x%lx Key=0x%lx Overlapped=%p NumBytes=%lu\n", Ret,
*ppCompletionKey, *lplpOverlapped, pIoStatusBlock->Information);
return Ret;
}
if (Ret == STATUS_PENDING)
Ret = wait_server_reply (&cookie);
/* If we were told to abandon our waiting, that means we've been
given a task to do */
if (Ret == STATUS_ABANDONED_WAIT_0)
{
SERVER_START_REQ(retrieve_assigned_io_completion)
{
req->handle = IoCompletionHandle;
Ret = wine_server_call (req);
if (Ret == STATUS_SUCCESS)
{
*ppCompletionKey = (ULONG_PTR)reply->completion_key;
*lplpOverlapped = reply->overlapped;
pIoStatusBlock->Information = reply->num_bytes;
}
}
SERVER_END_REQ;
}
pIoStatusBlock->u.Status = Ret;
TRACE ("Ret=0x%lx Key=0x%lx Overlapped=%p NumBytes=%lu\n", Ret,
*ppCompletionKey, *lplpOverlapped, pIoStatusBlock->Information);
return Ret;
}
/******************************************************************************
* NtSetIoCompletion (ntdll.@)
*/
NTSTATUS WINAPI NtSetIoCompletion
(HANDLE IoCompletionHandle, ULONG_PTR pCompletionKey,
LPOVERLAPPED lpOverlapped, ULONG NumberOfBytesTransferred,
ULONG NumberOfBytesToTransfer)
{
NTSTATUS Ret;
TRACE ("(0x%x, 0x%lx, %p, %lu, %lu)\n",
IoCompletionHandle, pCompletionKey, lpOverlapped,
NumberOfBytesTransferred, NumberOfBytesToTransfer);
if (NumberOfBytesTransferred)
WARN ("NumberOfBytesTransferred != 0 not handled\n");
SERVER_START_REQ(set_io_completion)
{
req->handle = IoCompletionHandle;
req->completion_key = (void *)pCompletionKey;
req->overlapped = lpOverlapped;
req->num_bytes = NumberOfBytesToTransfer;
Ret = wine_server_call (req);
}
SERVER_END_REQ;
TRACE ("Ret=0x%lx\n", Ret);
return Ret;
}
Index: Makefile.in
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/ntdll/Makefile.in,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Makefile.in 30 Mar 2007 20:41:27 -0000 1.7
+++ Makefile.in 31 Jul 2007 17:58:50 -0000 1.8
@@ -16,6 +16,7 @@
file.c \
heap.c \
heapinit.c \
+ iocomp.c \
large_int.c \
loader.c \
misc.c \
Index: ntdll.spec
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/ntdll/ntdll.spec,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- ntdll.spec 30 Mar 2007 20:41:27 -0000 1.48
+++ ntdll.spec 31 Jul 2007 17:58:50 -0000 1.49
@@ -2,7 +2,7 @@
type win32
debug_channels (atom cdrom client console debug delayhlp dll dosfs dosmem file fixup
- global heap heapcheck history int int21 int31 io loaddll local module ntdll process
+ global heap heapcheck history int int21 int31 io iocomp loaddll local module ntdll process
profile reg relay resource segment seh selector server snoop
string sync system tape task thread tid timer timestamp toolhelp ver virtual
vxd win32)
@@ -88,7 +88,7 @@
@ stdcall NtCreateEvent(long long long long long) NtCreateEvent
@ stub NtCreateEventPair
@ stdcall NtCreateFile(ptr long ptr ptr long long long ptr long long ptr) NtCreateFile
-@ stub NtCreateIoCompletion
+@ stdcall NtCreateIoCompletion(ptr long ptr long)
@ stdcall NtCreateKey(long long long long long long long) NtCreateKey
@ stdcall NtCreateMailslotFile(long long long long long long long long) NtCreateMailslotFile
@ stub NtCreateMutant
@@ -200,7 +200,7 @@
@ stub NtReleaseMutant
@ stub NtReleaseProcessMutant
@ stdcall NtReleaseSemaphore(long long ptr) NtReleaseSemaphore
-@ stub NtRemoveIoCompletion
+@ stdcall NtRemoveIoCompletion(long ptr ptr ptr ptr)
@ stdcall NtReplaceKey(ptr long ptr) NtReplaceKey
@ stub NtReplyPort
@ stdcall NtReplyWaitReceivePort(long long long long) NtReplyWaitReceivePort
@@ -228,7 +228,7 @@
@ stdcall NtSetInformationThread(long long long long) NtSetInformationThread
@ stub NtSetInformationToken
@ stdcall NtSetIntervalProfile(long long) NtSetIntervalProfile
-@ stub NtSetIoCompletion
+@ stdcall NtSetIoCompletion(long long ptr long long)
@ stub NtSetLdtEntries
@ stub NtSetLowEventPair
@ stub NtSetLowWaitHighEventPair