Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencsqrtns.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS Floppy Driver 00003 * Copyright (C) 2004, Vizzini (vizzini@plasmic.com) 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 * 00019 * PROJECT: ReactOS Floppy Driver 00020 * FILE: csqrtns.c 00021 * PURPOSE: Cancel-safe queue routines 00022 * PROGRAMMER: Vizzini (vizzini@plasmic.com) 00023 * REVISIONS: 00024 * 15-Feb-2004 vizzini - Created 00025 * NOTES: 00026 * - These functions provide the callbacks for the CSQ routines. 00027 * They will be called automatically by the IoCsqXxx() routines. 00028 * This driver uses the CSQ in the standard way. In addition to 00029 * queuing and de-queuing IRPs, the InsertIrp routine releases 00030 * a semaphore every time an IRP is queued, allowing a queue management 00031 * thread to properly drain the queue. 00032 * - Note that the semaphore can get ahead of the number of IRPs in the 00033 * queue if any are canceled; the queue management thread that de-queues 00034 * IRPs is coded with that in mind. 00035 * - For more information, see the csqtest driver in the ReactOS tree, 00036 * or the cancel sample in recent (3790+) Microsoft DDKs. 00037 * - Many of these routines are called at DISPATCH_LEVEL, due to the fact 00038 * that my lock choice is a spin lock. 00039 */ 00040 00041 #include "precomp.h" 00042 00043 /* Global CSQ struct that the CSQ functions initialize and use */ 00044 IO_CSQ Csq; 00045 00046 /* List and lock for the actual IRP queue */ 00047 LIST_ENTRY IrpQueue; 00048 KSPIN_LOCK IrpQueueLock; 00049 KSEMAPHORE QueueSemaphore; 00050 00051 /* 00052 * CSQ Callbacks 00053 */ 00054 00055 00056 VOID NTAPI 00057 CsqRemoveIrp(PIO_CSQ UnusedCsq, PIRP Irp) 00058 /* 00059 * FUNCTION: Remove an IRP from the queue 00060 * ARGUMENTS: 00061 * UnusedCsq: Pointer to CSQ context structure 00062 * Irp: Pointer to the IRP to remove from the queue 00063 * NOTES: 00064 * - Called under the protection of the queue lock 00065 */ 00066 { 00067 UNREFERENCED_PARAMETER(UnusedCsq); 00068 TRACE_(FLOPPY, "CSQ: Removing IRP 0x%p\n", Irp); 00069 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 00070 } 00071 00072 00073 PIRP NTAPI 00074 CsqPeekNextIrp(PIO_CSQ UnusedCsq, PIRP Irp, PVOID PeekContext) 00075 /* 00076 * FUNCTION: Find the next matching IRP in the queue 00077 * ARGUMENTS: 00078 * UnusedCsq: Pointer to CSQ context structure 00079 * Irp: Pointer to a starting IRP in the queue (i.e. start search here) 00080 * PeekContext: Unused 00081 * RETURNS: 00082 * Pointer to an IRP that is next in line to be removed, if one can be found 00083 * NOTES: 00084 * - This does *not* remove the IRP from the queue; it merely returns a pointer. 00085 * - Called under the protection of the queue lock 00086 */ 00087 { 00088 UNREFERENCED_PARAMETER(UnusedCsq); 00089 UNREFERENCED_PARAMETER(PeekContext); 00090 TRACE_(FLOPPY, "CSQ: Peeking for next IRP\n"); 00091 00092 if(Irp) 00093 return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry); 00094 00095 if(IsListEmpty(&IrpQueue)) 00096 return NULL; 00097 00098 return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry); 00099 } 00100 00101 00102 VOID NTAPI 00103 CsqAcquireLock(PIO_CSQ UnusedCsq, PKIRQL Irql) 00104 /* 00105 * FUNCTION: Acquire the queue lock 00106 * ARGUMENTS: 00107 * UnusedCsq: Pointer to CSQ context structure 00108 * Irql: Pointer to a variable to store the old irql into 00109 */ 00110 { 00111 UNREFERENCED_PARAMETER(UnusedCsq); 00112 INFO_(FLOPPY, "CSQ: Acquiring spin lock\n"); 00113 KeAcquireSpinLock(&IrpQueueLock, Irql); 00114 } 00115 00116 00117 VOID NTAPI 00118 CsqReleaseLock(PIO_CSQ UnusedCsq, KIRQL Irql) 00119 /* 00120 * FUNCTION: Release the queue lock 00121 * ARGUMENTS: 00122 * UnusedCsq: Pointer to CSQ context structure 00123 * Irql: IRQL to lower to on release 00124 */ 00125 { 00126 UNREFERENCED_PARAMETER(UnusedCsq); 00127 INFO_(FLOPPY, "CSQ: Releasing spin lock\n"); 00128 KeReleaseSpinLock(&IrpQueueLock, Irql); 00129 } 00130 00131 00132 VOID NTAPI 00133 CsqCompleteCanceledIrp(PIO_CSQ UnusedCsq, PIRP Irp) 00134 /* 00135 * FUNCTION: Complete a canceled IRP 00136 * ARGUMENTS: 00137 * UnusedCsq: Pointer to CSQ context structure 00138 * Irp: IRP to complete 00139 * NOTES: 00140 * - Perhaps we should complete with something besides NO_INCREMENT 00141 * - MS misspelled CANCELLED... sigh... 00142 */ 00143 { 00144 UNREFERENCED_PARAMETER(UnusedCsq); 00145 TRACE_(FLOPPY, "CSQ: Canceling irp 0x%p\n", Irp); 00146 Irp->IoStatus.Status = STATUS_CANCELLED; 00147 Irp->IoStatus.Information = 0; 00148 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00149 } 00150 00151 00152 VOID NTAPI 00153 CsqInsertIrp(PIO_CSQ UnusedCsq, PIRP Irp) 00154 /* 00155 * FUNCTION: Queue an IRP 00156 * ARGUMENTS: 00157 * UnusedCsq: Unused 00158 * Irp: IRP to add to the queue 00159 * NOTES: 00160 * - Called under the protection of the queue lock 00161 * - Releases the semaphore for each queued packet, which is how 00162 * the queue management thread knows that there might be 00163 * an IRP in the queue 00164 * - Note that the semaphore will get released more times than 00165 * the queue management thread will have IRPs to process, given 00166 * that at least one IRP is canceled at some point 00167 */ 00168 { 00169 UNREFERENCED_PARAMETER(UnusedCsq); 00170 TRACE_(FLOPPY, "CSQ: Inserting IRP 0x%p\n", Irp); 00171 InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry); 00172 KeReleaseSemaphore(&QueueSemaphore, 0, 1, FALSE); 00173 } 00174 Generated on Sat May 26 2012 04:26:54 for ReactOS by
1.7.6.1
|