ReactOS  0.4.13-dev-982-g9853eab
csqrtns.c
Go to the documentation of this file.
1 /*
2  * ReactOS Floppy Driver
3  * Copyright (C) 2004, Vizzini (vizzini@plasmic.com)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * PROJECT: ReactOS Floppy Driver
20  * FILE: csqrtns.c
21  * PURPOSE: Cancel-safe queue routines
22  * PROGRAMMER: Vizzini (vizzini@plasmic.com)
23  * REVISIONS:
24  * 15-Feb-2004 vizzini - Created
25  * NOTES:
26  * - These functions provide the callbacks for the CSQ routines.
27  * They will be called automatically by the IoCsqXxx() routines.
28  * This driver uses the CSQ in the standard way. In addition to
29  * queuing and de-queuing IRPs, the InsertIrp routine releases
30  * a semaphore every time an IRP is queued, allowing a queue management
31  * thread to properly drain the queue.
32  * - Note that the semaphore can get ahead of the number of IRPs in the
33  * queue if any are canceled; the queue management thread that de-queues
34  * IRPs is coded with that in mind.
35  * - For more information, see the csqtest driver in the ReactOS tree,
36  * or the cancel sample in recent (3790+) Microsoft DDKs.
37  * - Many of these routines are called at DISPATCH_LEVEL, due to the fact
38  * that my lock choice is a spin lock.
39  */
40 
41 #include "precomp.h"
42 
43 #include <debug.h>
44 
45 /* Global CSQ struct that the CSQ functions initialize and use */
47 
48 /* List and lock for the actual IRP queue */
52 
53 /*
54  * CSQ Callbacks
55  */
56 
57 
58 VOID NTAPI
60 /*
61  * FUNCTION: Remove an IRP from the queue
62  * ARGUMENTS:
63  * UnusedCsq: Pointer to CSQ context structure
64  * Irp: Pointer to the IRP to remove from the queue
65  * NOTES:
66  * - Called under the protection of the queue lock
67  */
68 {
69  UNREFERENCED_PARAMETER(UnusedCsq);
70  TRACE_(FLOPPY, "CSQ: Removing IRP 0x%p\n", Irp);
71  RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
72 }
73 
74 
75 PIRP NTAPI
77 /*
78  * FUNCTION: Find the next matching IRP in the queue
79  * ARGUMENTS:
80  * UnusedCsq: Pointer to CSQ context structure
81  * Irp: Pointer to a starting IRP in the queue (i.e. start search here)
82  * PeekContext: Unused
83  * RETURNS:
84  * Pointer to an IRP that is next in line to be removed, if one can be found
85  * NOTES:
86  * - This does *not* remove the IRP from the queue; it merely returns a pointer.
87  * - Called under the protection of the queue lock
88  */
89 {
90  UNREFERENCED_PARAMETER(UnusedCsq);
92  TRACE_(FLOPPY, "CSQ: Peeking for next IRP\n");
93 
94  if(Irp)
95  return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry);
96 
97  if(IsListEmpty(&IrpQueue))
98  return NULL;
99 
100  return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry);
101 }
102 
103 
104 VOID NTAPI
106 /*
107  * FUNCTION: Acquire the queue lock
108  * ARGUMENTS:
109  * UnusedCsq: Pointer to CSQ context structure
110  * Irql: Pointer to a variable to store the old irql into
111  */
112 {
113  UNREFERENCED_PARAMETER(UnusedCsq);
114  INFO_(FLOPPY, "CSQ: Acquiring spin lock\n");
116 }
117 
118 
119 VOID NTAPI
121 /*
122  * FUNCTION: Release the queue lock
123  * ARGUMENTS:
124  * UnusedCsq: Pointer to CSQ context structure
125  * Irql: IRQL to lower to on release
126  */
127 {
128  UNREFERENCED_PARAMETER(UnusedCsq);
129  INFO_(FLOPPY, "CSQ: Releasing spin lock\n");
131 }
132 
133 
134 VOID NTAPI
136 /*
137  * FUNCTION: Complete a canceled IRP
138  * ARGUMENTS:
139  * UnusedCsq: Pointer to CSQ context structure
140  * Irp: IRP to complete
141  * NOTES:
142  * - Perhaps we should complete with something besides NO_INCREMENT
143  * - MS misspelled CANCELLED... sigh...
144  */
145 {
146  UNREFERENCED_PARAMETER(UnusedCsq);
147  TRACE_(FLOPPY, "CSQ: Canceling irp 0x%p\n", Irp);
148  Irp->IoStatus.Status = STATUS_CANCELLED;
149  Irp->IoStatus.Information = 0;
151 }
152 
153 
154 VOID NTAPI
156 /*
157  * FUNCTION: Queue an IRP
158  * ARGUMENTS:
159  * UnusedCsq: Unused
160  * Irp: IRP to add to the queue
161  * NOTES:
162  * - Called under the protection of the queue lock
163  * - Releases the semaphore for each queued packet, which is how
164  * the queue management thread knows that there might be
165  * an IRP in the queue
166  * - Note that the semaphore will get released more times than
167  * the queue management thread will have IRPs to process, given
168  * that at least one IRP is canceled at some point
169  */
170 {
171  UNREFERENCED_PARAMETER(UnusedCsq);
172  TRACE_(FLOPPY, "CSQ: Inserting IRP 0x%p\n", Irp);
173  InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry);
175 }
VOID NTAPI CsqRemoveIrp(PIO_CSQ UnusedCsq, PIRP Irp)
Definition: csqrtns.c:59
#define INFO_(ch,...)
Definition: debug.h:159
VOID NTAPI CsqCompleteCanceledIrp(PIO_CSQ UnusedCsq, PIRP Irp)
Definition: csqrtns.c:135
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LIST_ENTRY IrpQueue
Definition: csqrtns.c:49
IRP
Definition: iotypes.h:2462
#define InsertTailList(ListHead, Entry)
_Out_ PKIRQL Irql
Definition: csq.h:179
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID NTAPI CsqInsertIrp(PIO_CSQ UnusedCsq, PIRP Irp)
Definition: csqrtns.c:155
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
KSEMAPHORE QueueSemaphore
Definition: csqrtns.c:51
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PIRP NTAPI CsqPeekNextIrp(PIO_CSQ UnusedCsq, PIRP Irp, PVOID PeekContext)
Definition: csqrtns.c:76
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define TRACE_(x)
Definition: compat.h:66
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
Definition: typedefs.h:117
VOID NTAPI CsqReleaseLock(PIO_CSQ UnusedCsq, KIRQL Irql)
Definition: csqrtns.c:120
KSPIN_LOCK IrpQueueLock
Definition: csqrtns.c:50
Definition: csq.h:222
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_In_opt_ PIRP _In_opt_ PVOID PeekContext
Definition: csq.h:159
IO_CSQ Csq
Definition: csqrtns.c:46
#define IO_NO_INCREMENT
Definition: iotypes.h:565
VOID NTAPI CsqAcquireLock(PIO_CSQ UnusedCsq, PKIRQL Irql)
Definition: csqrtns.c:105