Added Exclusive flag in afd, which is used by WSAAsyncSelect. Previous

exclusive selects should be completed with STATUS_CANCELLED when a new
exclusive one is posted.
Minor hack for the locked handle set.  Not dangerous but should be made
better.

svn path=/trunk/; revision=11811
This commit is contained in:
Art Yerkes 2004-11-25 23:36:36 +00:00
parent c350a8df8c
commit fd54d2585c
2 changed files with 48 additions and 12 deletions

View file

@ -1,4 +1,4 @@
/* $Id: select.c,v 1.7 2004/11/21 20:54:52 arty Exp $
/* $Id: select.c,v 1.8 2004/11/25 23:36:36 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/select.c
@ -50,7 +50,7 @@ VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq,
Poll->Irp->IoStatus.Information = Collected;
CopyBackStatus( PollReq->Handles,
PollReq->HandleCount );
UnlockHandles( PollReq->InternalUse, PollReq->HandleCount );
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
AFD_DbgPrint(MID_TRACE,("Completing\n"));
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
RemoveEntryList( &Poll->ListEntry );
@ -83,6 +83,30 @@ VOID SelectTimeout( PKDPC Dpc,
AFD_DbgPrint(MID_TRACE,("Timeout\n"));
}
VOID KillExclusiveSelects( PAFD_DEVICE_EXTENSION DeviceExt ) {
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
PAFD_ACTIVE_POLL Poll;
PIRP Irp;
PAFD_POLL_INFO PollReq;
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
for( ListEntry = DeviceExt->Polls.Flink;
ListEntry != &DeviceExt->Polls;
ListEntry = ListEntry->Flink ) {
Poll = CONTAINING_RECORD(ListEntry, AFD_ACTIVE_POLL, ListEntry);
if( Poll->Exclusive ) {
Irp = Poll->Irp;
PollReq = Irp->AssociatedIrp.SystemBuffer;
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
SignalSocket( Poll, PollReq, STATUS_CANCELLED, 0 );
}
}
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
}
NTSTATUS STDCALL
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
@ -97,15 +121,19 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
CopySize + sizeof(AFD_ACTIVE_POLL) - sizeof(AFD_POLL_INFO);
KIRQL OldIrql;
UINT i, Signalled = 0;
ULONG Exclusive = PollReq->Exclusive;
AFD_DbgPrint(MID_TRACE,("Called (HandleCount %d Timeout %d)\n",
PollReq->HandleCount,
(INT)(PollReq->Timeout.QuadPart)));
PollReq->InternalUse =
LockHandles( PollReq->Handles, PollReq->HandleCount );
SET_AFD_HANDLES(PollReq,
LockHandles( PollReq->Handles, PollReq->HandleCount ));
if( !PollReq->InternalUse ) {
if( Exclusive ) KillExclusiveSelects( DeviceExt );
if( !AFD_HANDLES(PollReq) ) {
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = -1;
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
@ -120,6 +148,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
if( Poll ) {
Poll->Irp = Irp;
Poll->DeviceExt = DeviceExt;
Poll->Exclusive = Exclusive;
KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
@ -132,14 +161,14 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
for( i = 0; i < PollReq->HandleCount; i++ ) {
if( !PollReq->InternalUse[i].Handle ) continue;
if( !AFD_HANDLES(PollReq)[i].Handle ) continue;
FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle;
FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle;
FCB = FileObject->FsContext;
if( (FCB->PollState & AFD_EVENT_CLOSE) ||
(PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) {
PollReq->InternalUse[i].Handle = 0;
AFD_HANDLES(PollReq)[i].Handle = 0;
PollReq->Handles[i].Events = 0;
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
Signalled++;
@ -248,14 +277,14 @@ BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );
for( i = 0; i < PollReq->HandleCount; i++ ) {
if( !PollReq->InternalUse[i].Handle ) continue;
if( !AFD_HANDLES(PollReq)[i].Handle ) continue;
FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle;
FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle;
FCB = FileObject->FsContext;
if( (FCB->PollState & AFD_EVENT_CLOSE) ||
(PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) {
PollReq->InternalUse[i].Handle = 0;
AFD_HANDLES(PollReq)[i].Handle = 0;
PollReq->Handles[i].Events = 0;
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
Signalled++;

View file

@ -1,4 +1,4 @@
/* $Id: afd.h,v 1.25 2004/11/21 20:54:52 arty Exp $
/* $Id: afd.h,v 1.26 2004/11/25 23:36:36 arty Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -65,6 +65,12 @@
#define SGID_CONNECTIONLESS 1 /* XXX Find this flag */
/* XXX This is a hack we should clean up later
* We do this in order to get some storage for the locked handle table
* Maybe I'll use some tail item in the irp instead */
#define AFD_HANDLES(x) ((PAFD_HANDLE)(x)->Exclusive)
#define SET_AFD_HANDLES(x,y) (((x)->Exclusive) = (ULONG)(y))
typedef struct _AFD_MAPBUF {
PVOID BufferAddress;
PMDL Mdl;
@ -83,6 +89,7 @@ typedef struct _AFD_ACTIVE_POLL {
KDPC TimeoutDpc;
KTIMER Timer;
PKEVENT EventObject;
BOOLEAN Exclusive;
} AFD_ACTIVE_POLL, *PAFD_ACTIVE_POLL;
typedef struct _IRP_LIST {