irp cancelation boiler plate, for irp queues you manage yourself
[reactos.git] / reactos / doc / irp cancel boilerplate.c
1
2
3 /*
4 Boiler plate for irp cancelation, for irp queues you manage yourself
5 -Gunnar
6 */
7
8
9
10 CancelRoutine(
11 DEV_OBJ Dev,
12 Irp
13 )
14 {
15 //don't need this since we have our own sync. protecting irp cancellation
16 IoReleaseCancelSpinLock(Irp->CancelIrql);
17
18 theLock = Irp->Tail.Overlay.DriverContext[3];
19
20 Lock(theLock);
21 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
22 Unlock(theLock);
23
24 Irp->IoStatus.Status = STATUS_CANCELLED;
25 Irp->IoStatus.Information = 0;
26
27 IoCompleteRequest(Irp, IO_NO_INCREMENT);
28
29 }
30
31
32 QUEUE_BOLIERPLATE
33 {
34 Lock(theLock);
35
36 Irp->Tail.Overlay.DriverContext[3] = &theLock;
37
38 IoSetCancelRoutine(Irp, CancelRoutine);
39 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
40 {
41 // IRP has already been cancelled (before we got to queue it),
42 // but we got to remove the cancel routine before the canceler could,
43 // so complete irp ourself
44
45 Unlock(theLock);
46
47 Irp->IoStatus.Status = STATUS_CANCELLED;
48 Irp->IoStatus.Information = 0;
49 IoCompleteRequest(Irp, IO_NO_INCREMENT);
50
51 return FALSE;
52 }
53
54 //else were ok
55
56
57 Irp->IoStatus.Status = STATUS_PENDING;
58 IoMarkIrpPending(Irp);
59
60 InsertTailList(Queue);
61
62 Unlock(theLock);
63
64 }
65
66
67 DEQUEUE_BOILERPLATE
68 {
69 Lock(theLock);
70
71 Irp = RemoveHeadList(Queue);
72
73 if (!IoSetCancelRoutine(Irp, NULL))
74 {
75 /*
76 Cancel routine WILL be called after we release the spinlock. It will try to remove
77 the irp from the list and cancel/complete this irp. Since we allready removed it,
78 make its ListEntry point to itself.
79 */
80
81 InitializeListHead(&Irp->Tail.Overlay.ListEntry);
82 }
83
84
85 /*
86 Cancel routine will NOT be called, canceled or not.
87 The Irp might have been canceled (Irp->Cancel flag set) but we don't care,
88 since we are to complete this Irp now anyways.
89 */
90
91 Unlock(theLock);
92
93 Irp->IoStatus.Status = STATUS_SUCCESS;
94 Irp->IoStatus.Information = 0;
95 IoCompleteRequest(Irp, IO_NO_INCREMENT);
96
97 }
98
99
100
101
102