- Don't call IoCompleteRequest while holding a spin lock because it can cause deadlocks

svn path=/branches/aicom-network-fixes/; revision=36102
This commit is contained in:
Cameron Gutman 2008-09-10 04:59:12 +00:00
parent e39210e30a
commit 8cf22aef05

View file

@ -86,8 +86,6 @@ static VOID SignalSocket(
} }
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount ); UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) ); if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
AFD_DbgPrint(MID_TRACE,("Completing\n"));
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
AFD_DbgPrint(MID_TRACE,("Done\n")); AFD_DbgPrint(MID_TRACE,("Done\n"));
} }
@ -113,6 +111,8 @@ static VOID SelectTimeout( PKDPC Dpc,
SignalSocket( Poll, NULL, PollReq, STATUS_TIMEOUT ); SignalSocket( Poll, NULL, PollReq, STATUS_TIMEOUT );
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
AFD_DbgPrint(MID_TRACE,("Timeout\n")); AFD_DbgPrint(MID_TRACE,("Timeout\n"));
} }
@ -146,6 +146,9 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
(!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) { (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) {
ZeroEvents( PollReq->Handles, PollReq->HandleCount ); ZeroEvents( PollReq->Handles, PollReq->HandleCount );
SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS ); SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS );
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
} }
} }
} }
@ -230,6 +233,9 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
SignalSocket( NULL, Irp, PollReq, Status ); SignalSocket( NULL, Irp, PollReq, Status );
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
return Status;
} else { } else {
PAFD_ACTIVE_POLL Poll = NULL; PAFD_ACTIVE_POLL Poll = NULL;
@ -383,6 +389,7 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
KIRQL OldIrql; KIRQL OldIrql;
PAFD_POLL_INFO PollReq; PAFD_POLL_INFO PollReq;
PKEVENT EventSelect = NULL; PKEVENT EventSelect = NULL;
PIRP Irp;
AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n", AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n",
DeviceExt, FileObject)); DeviceExt, FileObject));
@ -412,13 +419,17 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
while( ThePollEnt != &DeviceExt->Polls ) { while( ThePollEnt != &DeviceExt->Polls ) {
Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry ); Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry );
PollReq = Poll->Irp->AssociatedIrp.SystemBuffer; Irp = Poll->Irp;
PollReq = Irp->AssociatedIrp.SystemBuffer;
AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll)); AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll));
if( UpdatePollWithFCB( Poll, FileObject ) ) { if( UpdatePollWithFCB( Poll, FileObject ) ) {
ThePollEnt = ThePollEnt->Flink; ThePollEnt = ThePollEnt->Flink;
AFD_DbgPrint(MID_TRACE,("Signalling socket\n")); AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS ); SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS );
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
} else } else
ThePollEnt = ThePollEnt->Flink; ThePollEnt = ThePollEnt->Flink;
} }