* Sync up to trunk HEAD (r62502).
[reactos.git] / media / 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 /*
42 Irp has already been cancelled (before we got to queue it),
43 and we got to remove the cancel routine before the canceler could,
44 so we cancel/complete the irp ourself.
45 */
46
47 Unlock(theLock);
48
49 Irp->IoStatus.Status = STATUS_CANCELLED;
50 Irp->IoStatus.Information = 0;
51 IoCompleteRequest(Irp, IO_NO_INCREMENT);
52
53 return FALSE;
54 }
55
56 //else were ok
57
58
59 Irp->IoStatus.Status = STATUS_PENDING;
60 IoMarkIrpPending(Irp);
61
62 InsertTailList(Queue);
63
64 Unlock(theLock);
65
66 }
67
68
69 DEQUEUE_BOILERPLATE
70 {
71 Lock(theLock);
72
73 Irp = RemoveHeadList(Queue);
74
75 if (!IoSetCancelRoutine(Irp, NULL))
76 {
77 /*
78 Cancel routine WILL be called after we release the spinlock. It will try to remove
79 the irp from the list and cancel/complete this irp. Since we allready removed it,
80 make its ListEntry point to itself.
81 */
82
83 InitializeListHead(&Irp->Tail.Overlay.ListEntry);
84
85 Unlock(theLock);
86
87 return;
88 }
89
90
91 /*
92 Cancel routine will NOT be called, canceled or not.
93 The Irp might have been canceled (Irp->Cancel flag set) but we don't care,
94 since we are to complete this Irp now anyways.
95 */
96
97 Unlock(theLock);
98
99 Irp->IoStatus.Status = STATUS_SUCCESS;
100 Irp->IoStatus.Information = 0;
101 IoCompleteRequest(Irp, IO_NO_INCREMENT);
102
103 }