mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Prevent some deadlock scenarios by unlocking the FCB while calling into
tcpip.sys. svn path=/trunk/; revision=11625
This commit is contained in:
parent
0af675ba07
commit
dea7f87980
6 changed files with 81 additions and 35 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: lock.c,v 1.3 2004/09/23 06:42:16 arty Exp $
|
||||
/* $Id: lock.c,v 1.4 2004/11/12 07:34:56 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/lock.c
|
||||
|
@ -100,7 +100,8 @@ VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count ) {
|
|||
UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PVOID CurrentThread = KeGetCurrentThread();
|
||||
KIRQL CurrentIrql = KeGetCurrentIrql();
|
||||
|
||||
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE,("Called on %x, attempting to lock\n", FCB));
|
||||
|
||||
|
@ -122,8 +123,8 @@ UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
|
|||
}
|
||||
|
||||
|
||||
if( CurrentIrql == PASSIVE_LEVEL ) {
|
||||
ExAcquireFastMutex( &FCB->Mutex );
|
||||
|
||||
while( FCB->Locked ) {
|
||||
AFD_DbgPrint
|
||||
(MID_TRACE,("FCB %x is locked, waiting for notification\n",
|
||||
|
@ -135,24 +136,23 @@ UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
|
|||
FALSE,
|
||||
NULL );
|
||||
ExAcquireFastMutex( &FCB->Mutex );
|
||||
if( Status == STATUS_SUCCESS ) break;
|
||||
}
|
||||
FCB->Locked = TRUE;
|
||||
FCB->CurrentThread = CurrentThread;
|
||||
FCB->LockCount++;
|
||||
ExReleaseFastMutex( &FCB->Mutex );
|
||||
} else { /* Nothing since we're not at PASSIVE_LEVEL */
|
||||
FCB->Locked = TRUE;
|
||||
FCB->CurrentThread = CurrentThread;
|
||||
FCB->LockCount++;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE,("Got lock (%d).\n", FCB->LockCount));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID SocketStateUnlock( PAFD_FCB FCB ) {
|
||||
PVOID CurrentThread = KeGetCurrentThread();
|
||||
ASSERT(FCB->LockCount > 0);
|
||||
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
|
||||
ExAcquireFastMutex( &FCB->Mutex );
|
||||
FCB->LockCount--;
|
||||
|
||||
if( !FCB->LockCount ) {
|
||||
|
@ -162,8 +162,10 @@ VOID SocketStateUnlock( PAFD_FCB FCB ) {
|
|||
AFD_DbgPrint(MAX_TRACE,("Unlocked.\n"));
|
||||
KePulseEvent( &FCB->StateLockedEvent, IO_NETWORK_INCREMENT, FALSE );
|
||||
} else {
|
||||
AFD_DbgPrint(MID_TRACE,("Lock count %d\n", FCB->LockCount));
|
||||
AFD_DbgPrint(MAX_TRACE,("New lock count: %d (Thr: %x)\n",
|
||||
FCB->LockCount, CurrentThread));
|
||||
}
|
||||
ExReleaseFastMutex( &FCB->Mutex );
|
||||
}
|
||||
|
||||
NTSTATUS DDKAPI UnlockAndMaybeComplete
|
||||
|
@ -204,3 +206,13 @@ NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
|
|||
return UnlockAndMaybeComplete( FCB, STATUS_PENDING, Irp, 0, NULL, FALSE );
|
||||
}
|
||||
|
||||
VOID SocketCalloutEnter( PAFD_FCB FCB ) {
|
||||
ASSERT(FCB->Locked);
|
||||
FCB->Critical = TRUE;
|
||||
SocketStateUnlock( FCB );
|
||||
}
|
||||
|
||||
VOID SocketCalloutLeave( PAFD_FCB FCB ) {
|
||||
FCB->Critical = FALSE;
|
||||
SocketAcquireStateLock( FCB );
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: main.c,v 1.7 2004/09/23 06:42:16 arty Exp $
|
||||
/* $Id: main.c,v 1.8 2004/11/12 07:34:56 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/main.c
|
||||
|
@ -151,7 +151,8 @@ VOID DestroySocket( PAFD_FCB FCB ) {
|
|||
InFlightRequest[2] = &FCB->SendIrp;
|
||||
|
||||
/* Return early here because we might be called in the mean time. */
|
||||
if( FCB->ListenIrp.InFlightRequest ||
|
||||
if( FCB->Critical ||
|
||||
FCB->ListenIrp.InFlightRequest ||
|
||||
FCB->ReceiveIrp.InFlightRequest ||
|
||||
FCB->SendIrp.InFlightRequest ) {
|
||||
AFD_DbgPrint(MIN_TRACE,("Leaving socket alive (%x %x %x)\n",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: read.c,v 1.7 2004/10/03 20:36:45 arty Exp $
|
||||
/* $Id: read.c,v 1.8 2004/11/12 07:34:56 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/read.c
|
||||
|
@ -139,6 +139,8 @@ NTSTATUS DDKAPI ReceiveComplete
|
|||
AFD_DbgPrint(MID_TRACE,
|
||||
("Exhausted our buffer. Requesting new: %x\n", FCB));
|
||||
|
||||
SocketCalloutEnter( FCB );
|
||||
|
||||
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
|
||||
IrpSp->FileObject,
|
||||
TDI_RECEIVE_NORMAL,
|
||||
|
@ -147,6 +149,8 @@ NTSTATUS DDKAPI ReceiveComplete
|
|||
&FCB->ReceiveIrp.Iosb,
|
||||
ReceiveComplete,
|
||||
FCB );
|
||||
|
||||
SocketCalloutLeave( FCB );
|
||||
}
|
||||
} else {
|
||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
|
||||
|
@ -204,6 +208,9 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
FCB->Recv.Content = 0;
|
||||
FCB->Recv.BytesUsed = 0;
|
||||
AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
|
||||
|
||||
SocketCalloutEnter( FCB );
|
||||
|
||||
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
|
||||
FCB->Connection.Object,
|
||||
TDI_RECEIVE_NORMAL,
|
||||
|
@ -212,6 +219,8 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
&FCB->ReceiveIrp.Iosb,
|
||||
ReceiveComplete,
|
||||
FCB );
|
||||
|
||||
SocketCalloutLeave( FCB );
|
||||
} else Status = STATUS_SUCCESS;
|
||||
|
||||
if( NT_SUCCESS(Status) )
|
||||
|
@ -346,6 +355,8 @@ PacketSocketRecvComplete(
|
|||
|
||||
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
|
||||
/* Now relaunch the datagram request */
|
||||
SocketCalloutEnter( FCB );
|
||||
|
||||
Status = TdiReceiveDatagram
|
||||
( &FCB->ReceiveIrp.InFlightRequest,
|
||||
FCB->AddressFile.Object,
|
||||
|
@ -356,6 +367,8 @@ PacketSocketRecvComplete(
|
|||
&FCB->ReceiveIrp.Iosb,
|
||||
PacketSocketRecvComplete,
|
||||
FCB );
|
||||
|
||||
SocketCalloutLeave( FCB );
|
||||
}
|
||||
|
||||
SocketStateUnlock( FCB );
|
||||
|
@ -381,8 +394,8 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
return UnlockAndMaybeComplete
|
||||
( FCB, STATUS_UNSUCCESSFUL, Irp, 0, NULL, FALSE );
|
||||
if( !(RecvReq = LockRequest( Irp, IrpSp )) )
|
||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
|
||||
Irp, 0, NULL, FALSE );
|
||||
return UnlockAndMaybeComplete
|
||||
( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE );
|
||||
|
||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
||||
ListEntry = RemoveHeadList( &FCB->DatagramList );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: write.c,v 1.9 2004/10/03 21:16:27 arty Exp $
|
||||
/* $Id: write.c,v 1.10 2004/11/12 07:34:56 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/write.c
|
||||
|
@ -109,6 +109,9 @@ NTSTATUS DDKAPI SendComplete
|
|||
/* Some data is still waiting */
|
||||
if( FCB->Send.BytesUsed ) {
|
||||
FCB->PollState &= ~AFD_EVENT_SEND;
|
||||
|
||||
SocketCalloutEnter( FCB );
|
||||
|
||||
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
|
||||
IrpSp->FileObject,
|
||||
0,
|
||||
|
@ -117,6 +120,8 @@ NTSTATUS DDKAPI SendComplete
|
|||
&FCB->SendIrp.Iosb,
|
||||
SendComplete,
|
||||
FCB );
|
||||
|
||||
SocketCalloutLeave( FCB );
|
||||
} else {
|
||||
FCB->PollState |= AFD_EVENT_SEND;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
|
@ -219,6 +224,10 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
if( TotalBytesCopied > 0 ) {
|
||||
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
|
||||
|
||||
FCB->SendIrp.InFlightRequest = (PVOID)1; /* Placeholder */
|
||||
|
||||
SocketCalloutEnter( FCB );
|
||||
|
||||
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
|
||||
FCB->Connection.Object,
|
||||
0,
|
||||
|
@ -228,6 +237,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
SendComplete,
|
||||
FCB );
|
||||
|
||||
SocketCalloutLeave( FCB );
|
||||
|
||||
if( Status == STATUS_PENDING )
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
|
@ -265,6 +276,8 @@ NTSTATUS DDKAPI PacketSocketSendComplete
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SocketStateUnlock( FCB );
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -301,6 +314,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
/* Check the size of the Address given ... */
|
||||
|
||||
if( TargetAddress ) {
|
||||
SocketCalloutEnter( FCB );
|
||||
|
||||
Status = TdiSendDatagram
|
||||
( &FCB->SendIrp.InFlightRequest,
|
||||
FCB->AddressFile.Object,
|
||||
|
@ -311,6 +326,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
PacketSocketSendComplete,
|
||||
FCB );
|
||||
|
||||
SocketCalloutLeave( FCB );
|
||||
|
||||
ExFreePool( TargetAddress );
|
||||
} else Status = STATUS_NO_MEMORY;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: afd.h,v 1.20 2004/09/05 04:26:30 arty Exp $
|
||||
/* $Id: afd.h,v 1.21 2004/11/12 07:34:56 arty Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include <shared.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <roscfg.h>
|
||||
#include <rosrtl/string.h>
|
||||
#include <winsock2.h>
|
||||
#include <ddk/tdi.h>
|
||||
|
@ -109,7 +110,7 @@ typedef struct _AFD_STORED_DATAGRAM {
|
|||
} AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
|
||||
|
||||
typedef struct _AFD_FCB {
|
||||
BOOLEAN Locked;
|
||||
BOOLEAN Locked, Critical;
|
||||
UINT State, Flags;
|
||||
KIRQL OldIrql;
|
||||
UINT LockCount;
|
||||
|
@ -182,6 +183,8 @@ VOID SocketStateUnlock( PAFD_FCB FCB );
|
|||
NTSTATUS LostSocket( PIRP Irp, BOOL ShouldUnlockIrp );
|
||||
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||
VOID SocketCalloutEnter( PAFD_FCB FCB );
|
||||
VOID SocketCalloutLeave( PAFD_FCB FCB );
|
||||
|
||||
/* main.c */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.13 2004/08/15 22:51:57 chorns Exp $
|
||||
# $Id: makefile,v 1.14 2004/11/12 07:34:55 arty Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
|
@ -11,7 +11,7 @@ TARGET_PCH = include/afd.h
|
|||
TARGET_DDKLIBS = \
|
||||
$(PATH_TO_TOP)/dk/w32/lib/pseh.a
|
||||
|
||||
TARGET_CFLAGS = -I./include -I$(PATH_TO_TOP)/w32api/include/ddk -I$(PATH_TO_TOP)/include/afd -DDBG -D__USE_W32API -Werror -Wall
|
||||
TARGET_CFLAGS = -I./include -I$(PATH_TO_TOP)/w32api/include/ddk -I$(PATH_TO_TOP)/include/afd -D__USE_W32API -Werror -Wall
|
||||
|
||||
TARGET_OBJECTS = \
|
||||
afd/bind.o \
|
||||
|
|
Loading…
Reference in a new issue