mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-24 01:13:04 -05:00
sys: FspIoqStop()
This commit is contained in:
parent
0f0b1f2c46
commit
6ba60198ab
@ -156,19 +156,18 @@ FAST_IO_RELEASE_FOR_CCFLUSH FspReleaseForCcFlush;
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
KSPIN_LOCK SpinLock;
|
KSPIN_LOCK SpinLock;
|
||||||
int Enabled;
|
BOOLEAN Stopped;
|
||||||
KEVENT PendingIrpEvent;
|
KEVENT PendingIrpEvent;
|
||||||
LIST_ENTRY PendingIrpList, ProcessIrpList;
|
LIST_ENTRY PendingIrpList, ProcessIrpList;
|
||||||
IO_CSQ PendingIoCsq, ProcessIoCsq;
|
IO_CSQ PendingIoCsq, ProcessIoCsq;
|
||||||
} FSP_IOQ;
|
} FSP_IOQ;
|
||||||
VOID FspIoqInitialize(FSP_IOQ *Ioq);
|
VOID FspIoqInitialize(FSP_IOQ *Ioq);
|
||||||
BOOLEAN FspIoqEnabled(FSP_IOQ *Ioq);
|
VOID FspIoqStop(FSP_IOQ *Ioq);
|
||||||
VOID FspIoqDisable(FSP_IOQ *Ioq);
|
BOOLEAN FspIoqStopped(FSP_IOQ *Ioq);
|
||||||
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
|
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||||
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis);
|
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis);
|
||||||
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||||
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
||||||
VOID FspIoqCancelAll(FSP_IOQ *Ioq);
|
|
||||||
|
|
||||||
/* device extensions */
|
/* device extensions */
|
||||||
enum
|
enum
|
||||||
|
@ -151,10 +151,10 @@ static NTSTATUS FspFsvrtTransact(
|
|||||||
Response = (PVOID)((PUINT8)Response + Response->Size);
|
Response = (PVOID)((PUINT8)Response + Response->Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for a pending IRP */
|
/* wait for an IRP to arrive */
|
||||||
while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, (ULONG)-1L)))
|
while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, (ULONG)-1L)))
|
||||||
{
|
{
|
||||||
if (!FspIoqEnabled(&FsvrtDeviceExtension->Ioq))
|
if (FspIoqStopped(&FsvrtDeviceExtension->Ioq))
|
||||||
return STATUS_CANCELLED;
|
return STATUS_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,10 +169,15 @@ static NTSTATUS FspFsvrtTransact(
|
|||||||
|
|
||||||
if (!FspIoqStartProcessingIrp(&FsvrtDeviceExtension->Ioq, PendingIrp))
|
if (!FspIoqStartProcessingIrp(&FsvrtDeviceExtension->Ioq, PendingIrp))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This can only happen if the Ioq was stopped. Abandon everything
|
||||||
|
* and return STATUS_CANCELLED. Any IRP's in the Pending and Process
|
||||||
|
* queues of the Ioq will be cancelled during FspIoqStop(). We must
|
||||||
|
* also cancel the PendingIrp we have in our hands.
|
||||||
|
*/
|
||||||
|
ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq));
|
||||||
FspCompleteRequest(PendingIrp, STATUS_CANCELLED);
|
FspCompleteRequest(PendingIrp, STATUS_CANCELLED);
|
||||||
if (!LoopedOnce)
|
return STATUS_CANCELLED;
|
||||||
return STATUS_CANCELLED;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Request = PendingIrp->Tail.Overlay.DriverContext[0];
|
Request = PendingIrp->Tail.Overlay.DriverContext[0];
|
||||||
|
@ -50,15 +50,15 @@
|
|||||||
*
|
*
|
||||||
* Event Object
|
* Event Object
|
||||||
*
|
*
|
||||||
* The FSP_IOQ includes a manual event object. The event object remains
|
* The FSP_IOQ includes a manual event object. The event object becomes
|
||||||
* signaled when the FSP_IOQ object is disabled or when the Pending queue
|
* signaled when the FSP_IOQ object is stopped or for as long as the Pending
|
||||||
* is not empty.
|
* queue is not empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static NTSTATUS FspIoqPendingInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
static NTSTATUS FspIoqPendingInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
||||||
if (0 >= Ioq->Enabled)
|
if (Ioq->Stopped)
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
InsertTailList(&Ioq->PendingIrpList, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(&Ioq->PendingIrpList, &Irp->Tail.Overlay.ListEntry);
|
||||||
/* list is not empty; wake up any waiters */
|
/* list is not empty; wake up any waiters */
|
||||||
@ -69,7 +69,7 @@ static NTSTATUS FspIoqPendingInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertCo
|
|||||||
static VOID FspIoqPendingRemoveIrp(PIO_CSQ IoCsq, PIRP Irp)
|
static VOID FspIoqPendingRemoveIrp(PIO_CSQ IoCsq, PIRP Irp)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
||||||
if (RemoveEntryList(&Irp->Tail.Overlay.ListEntry) && 0 < Ioq->Enabled)
|
if (RemoveEntryList(&Irp->Tail.Overlay.ListEntry) && !Ioq->Stopped)
|
||||||
/* list is empty; future threads should go to sleep */
|
/* list is empty; future threads should go to sleep */
|
||||||
KeClearEvent(&Ioq->PendingIrpEvent);
|
KeClearEvent(&Ioq->PendingIrpEvent);
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ static VOID FspIoqPendingRemoveIrp(PIO_CSQ IoCsq, PIRP Irp)
|
|||||||
static PIRP FspIoqPendingPeekNextIrp(PIO_CSQ IoCsq, PIRP Irp, PVOID PeekContext)
|
static PIRP FspIoqPendingPeekNextIrp(PIO_CSQ IoCsq, PIRP Irp, PVOID PeekContext)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
||||||
if (!PeekContext && 0 >= Ioq->Enabled)
|
if (!PeekContext && Ioq->Stopped)
|
||||||
return 0;
|
return 0;
|
||||||
PLIST_ENTRY Head = &Ioq->PendingIrpList;
|
PLIST_ENTRY Head = &Ioq->PendingIrpList;
|
||||||
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
||||||
@ -104,7 +104,7 @@ static VOID FspIoqPendingCompleteCanceledIrp(PIO_CSQ IoCsq, PIRP Irp)
|
|||||||
static NTSTATUS FspIoqProcessInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
static NTSTATUS FspIoqProcessInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, ProcessIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, ProcessIoCsq);
|
||||||
if (0 >= Ioq->Enabled)
|
if (Ioq->Stopped)
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
InsertTailList(&Ioq->ProcessIrpList, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(&Ioq->ProcessIrpList, &Irp->Tail.Overlay.ListEntry);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -118,10 +118,12 @@ static VOID FspIoqProcessRemoveIrp(PIO_CSQ IoCsq, PIRP Irp)
|
|||||||
static PIRP FspIoqProcessPeekNextIrp(PIO_CSQ IoCsq, PIRP Irp, PVOID PeekContext)
|
static PIRP FspIoqProcessPeekNextIrp(PIO_CSQ IoCsq, PIRP Irp, PVOID PeekContext)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, ProcessIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, ProcessIoCsq);
|
||||||
if (!PeekContext && 0 >= Ioq->Enabled)
|
if (!PeekContext && Ioq->Stopped)
|
||||||
return 0;
|
return 0;
|
||||||
PLIST_ENTRY Head = &Ioq->ProcessIrpList;
|
PLIST_ENTRY Head = &Ioq->ProcessIrpList;
|
||||||
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
PLIST_ENTRY Entry = 0 == Irp ? Head->Flink : Irp->Tail.Overlay.ListEntry.Flink;
|
||||||
|
if (!PeekContext)
|
||||||
|
return Head != Entry ? CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry) : 0;
|
||||||
for (; Head != Entry; Entry = Entry->Flink)
|
for (; Head != Entry; Entry = Entry->Flink)
|
||||||
{
|
{
|
||||||
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
|
||||||
@ -169,28 +171,33 @@ VOID FspIoqInitialize(FSP_IOQ *Ioq)
|
|||||||
FspIoqProcessAcquireLock,
|
FspIoqProcessAcquireLock,
|
||||||
FspIoqProcessReleaseLock,
|
FspIoqProcessReleaseLock,
|
||||||
FspIoqProcessCompleteCanceledIrp);
|
FspIoqProcessCompleteCanceledIrp);
|
||||||
Ioq->Enabled = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FspIoqEnabled(FSP_IOQ *Ioq)
|
VOID FspIoqStop(FSP_IOQ *Ioq)
|
||||||
|
{
|
||||||
|
KIRQL Irql;
|
||||||
|
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
|
||||||
|
Ioq->Stopped = TRUE;
|
||||||
|
/* we are being stopped, permanently wake up waiters */
|
||||||
|
KeSetEvent(&Ioq->PendingIrpEvent, 1, FALSE);
|
||||||
|
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
|
||||||
|
PIRP Irp;
|
||||||
|
while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, 0)))
|
||||||
|
FspIoqPendingCompleteCanceledIrp(&Ioq->PendingIoCsq, Irp);
|
||||||
|
while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->ProcessIoCsq, 0)))
|
||||||
|
FspIoqProcessCompleteCanceledIrp(&Ioq->ProcessIoCsq, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN FspIoqStopped(FSP_IOQ *Ioq)
|
||||||
{
|
{
|
||||||
BOOLEAN Result;
|
BOOLEAN Result;
|
||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
|
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
|
||||||
Result = 0 < Ioq->Enabled;
|
Result = Ioq->Stopped;
|
||||||
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
|
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspIoqDisable(FSP_IOQ *Ioq)
|
|
||||||
{
|
|
||||||
KIRQL Irql;
|
|
||||||
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
|
|
||||||
Ioq->Enabled = 0;
|
|
||||||
KeSetEvent(&Ioq->PendingIrpEvent, 1, FALSE);
|
|
||||||
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
|
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -224,12 +231,3 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint)
|
|||||||
{
|
{
|
||||||
return IoCsqRemoveNextIrp(&Ioq->ProcessIoCsq, (PVOID)IrpHint);
|
return IoCsqRemoveNextIrp(&Ioq->ProcessIoCsq, (PVOID)IrpHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspIoqCancelAll(FSP_IOQ *Ioq)
|
|
||||||
{
|
|
||||||
PIRP Irp;
|
|
||||||
while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, 0)))
|
|
||||||
FspIoqPendingCompleteCanceledIrp(&Ioq->PendingIoCsq, Irp);
|
|
||||||
while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->ProcessIoCsq, 0)))
|
|
||||||
FspIoqProcessCompleteCanceledIrp(&Ioq->ProcessIoCsq, Irp);
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user