ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

devqueue.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/ke/devqueue.c
00005  * PURPOSE:         Implement device queues
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* FUNCTIONS *****************************************************************/
00016 
00017 /*
00018  * @implemented
00019  */
00020 VOID
00021 NTAPI
00022 KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
00023 {
00024     /* Initialize the Header */
00025     DeviceQueue->Type = DeviceQueueObject;
00026     DeviceQueue->Size = sizeof(KDEVICE_QUEUE);
00027 
00028     /* Initialize the Listhead and Spinlock */
00029     InitializeListHead(&DeviceQueue->DeviceListHead);
00030     KeInitializeSpinLock(&DeviceQueue->Lock);
00031 
00032     /* Set it as busy */
00033     DeviceQueue->Busy=FALSE;
00034 }
00035 
00036 /*
00037  * @implemented
00038  */
00039 BOOLEAN
00040 NTAPI
00041 KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
00042                     IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
00043 {
00044     KLOCK_QUEUE_HANDLE DeviceLock;
00045     BOOLEAN Inserted;
00046     ASSERT_DEVICE_QUEUE(DeviceQueue);
00047 
00048     DPRINT("KeInsertDeviceQueue() DevQueue %p, Entry %p\n", DeviceQueue, DeviceQueueEntry);
00049 
00050     /* Lock the queue */
00051     KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
00052 
00053     /* Check if it's not busy */
00054     if (!DeviceQueue->Busy)
00055     {
00056         /* Set it as busy */
00057         Inserted = FALSE;
00058         DeviceQueue->Busy = TRUE;
00059     }
00060     else
00061     {
00062         /* Insert it into the list */
00063         Inserted = TRUE;
00064         InsertTailList(&DeviceQueue->DeviceListHead,
00065                        &DeviceQueueEntry->DeviceListEntry);
00066     }
00067 
00068     /* Sert the Insert state into the entry */
00069     DeviceQueueEntry->Inserted = Inserted;
00070 
00071     /* Release the lock */
00072     KiReleaseDeviceQueueLock(&DeviceLock);
00073 
00074     /* Return the state */
00075     return Inserted;
00076 }
00077 
00078 /*
00079  * @implemented
00080  */
00081 BOOLEAN
00082 NTAPI
00083 KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
00084                          IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
00085                          IN ULONG SortKey)
00086 {
00087     KLOCK_QUEUE_HANDLE DeviceLock;
00088     BOOLEAN Inserted;
00089     PLIST_ENTRY NextEntry;
00090     PKDEVICE_QUEUE_ENTRY LastEntry;
00091     ASSERT_DEVICE_QUEUE(DeviceQueue);
00092 
00093     DPRINT("KeInsertByKeyDeviceQueue() DevQueue %p, Entry %p, SortKey 0x%x\n", DeviceQueue, DeviceQueueEntry, SortKey);
00094 
00095     /* Lock the queue */
00096     KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
00097 
00098     /* Set the Sort Key */
00099     DeviceQueueEntry->SortKey = SortKey;
00100 
00101     /* Check if it's not busy */
00102     if (!DeviceQueue->Busy)
00103     {
00104         /* Set it as busy */
00105         Inserted = FALSE;
00106         DeviceQueue->Busy = TRUE;
00107     }
00108     else
00109     {
00110         /* Make sure the list isn't empty */
00111         NextEntry = &DeviceQueue->DeviceListHead;
00112         if (!IsListEmpty(NextEntry))
00113         {
00114             /* Get the last entry */
00115             LastEntry = CONTAINING_RECORD(NextEntry->Blink,
00116                                           KDEVICE_QUEUE_ENTRY,
00117                                           DeviceListEntry);
00118 
00119             /* Check if our sort key is lower */
00120             if (SortKey < LastEntry->SortKey)
00121             {
00122                 /* Loop each sort key */
00123                 do
00124                 {
00125                     /* Get the next entry */
00126                     NextEntry = NextEntry->Flink;
00127                     LastEntry = CONTAINING_RECORD(NextEntry,
00128                                                   KDEVICE_QUEUE_ENTRY,
00129                                                   DeviceListEntry);
00130 
00131                     /* Keep looping until we find a place to insert */
00132                 } while (SortKey >= LastEntry->SortKey);
00133             }
00134         }
00135 
00136         /* Now insert us */
00137         InsertTailList(NextEntry, &DeviceQueueEntry->DeviceListEntry);
00138         Inserted = TRUE;
00139     }
00140 
00141     /* Release the lock */
00142     KiReleaseDeviceQueueLock(&DeviceLock);
00143 
00144     /* Return the state */
00145     return Inserted;
00146 }
00147 
00148 /*
00149  * @implemented
00150  */
00151 PKDEVICE_QUEUE_ENTRY
00152 NTAPI
00153 KeRemoveDeviceQueue(IN PKDEVICE_QUEUE   DeviceQueue)
00154 {
00155     PLIST_ENTRY ListEntry;
00156     PKDEVICE_QUEUE_ENTRY ReturnEntry;
00157     KLOCK_QUEUE_HANDLE DeviceLock;
00158     ASSERT_DEVICE_QUEUE(DeviceQueue);
00159 
00160     DPRINT("KeRemoveDeviceQueue() DevQueue %p\n", DeviceQueue);
00161 
00162     /* Lock the queue */
00163     KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
00164     ASSERT(DeviceQueue->Busy);
00165 
00166     /* Check if this is an empty queue */
00167     if (IsListEmpty(&DeviceQueue->DeviceListHead))
00168     {
00169         /* Set it to idle and return nothing*/
00170         DeviceQueue->Busy = FALSE;
00171         ReturnEntry = NULL;
00172     }
00173     else
00174     {
00175         /* Remove the Entry from the List */
00176         ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
00177         ReturnEntry = CONTAINING_RECORD(ListEntry,
00178                                         KDEVICE_QUEUE_ENTRY,
00179                                         DeviceListEntry);
00180 
00181         /* Set it as non-inserted */
00182         ReturnEntry->Inserted = FALSE;
00183     }
00184 
00185     /* Release the lock */
00186     KiReleaseDeviceQueueLock(&DeviceLock);
00187 
00188     /* Return the entry */
00189     return ReturnEntry;
00190 }
00191 
00192 /*
00193  * @implemented
00194  */
00195 PKDEVICE_QUEUE_ENTRY
00196 NTAPI
00197 KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
00198                          IN ULONG SortKey)
00199 {
00200     PLIST_ENTRY NextEntry;
00201     PKDEVICE_QUEUE_ENTRY ReturnEntry;
00202     KLOCK_QUEUE_HANDLE DeviceLock;
00203     ASSERT_DEVICE_QUEUE(DeviceQueue);
00204 
00205     DPRINT("KeRemoveByKeyDeviceQueue() DevQueue %p, SortKey 0x%x\n", DeviceQueue, SortKey);
00206 
00207     /* Lock the queue */
00208     KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
00209     ASSERT(DeviceQueue->Busy);
00210 
00211     /* Check if this is an empty queue */
00212     if (IsListEmpty(&DeviceQueue->DeviceListHead))
00213     {
00214         /* Set it to idle and return nothing*/
00215         DeviceQueue->Busy = FALSE;
00216         ReturnEntry = NULL;
00217     }
00218     else
00219     {
00220         /* If SortKey is greater than the last key, then return the first entry right away */
00221         NextEntry = &DeviceQueue->DeviceListHead;
00222         ReturnEntry = CONTAINING_RECORD(NextEntry->Blink,
00223                                         KDEVICE_QUEUE_ENTRY,
00224                                         DeviceListEntry);
00225 
00226         /* Check if we can just get the first entry */
00227         if (ReturnEntry->SortKey <= SortKey)
00228         {
00229             /* Get the first entry */
00230             ReturnEntry = CONTAINING_RECORD(NextEntry->Flink,
00231                                             KDEVICE_QUEUE_ENTRY,
00232                                             DeviceListEntry);
00233         }
00234         else
00235         {
00236             /* Loop the list */
00237             NextEntry = DeviceQueue->DeviceListHead.Flink;
00238             while (TRUE)
00239             {
00240                 /* Make sure we don't go beyond the end of the queue */
00241                 ASSERT(NextEntry != &DeviceQueue->DeviceListHead);
00242 
00243                 /* Get the next entry and check if the key is low enough */
00244                 ReturnEntry = CONTAINING_RECORD(NextEntry,
00245                                                 KDEVICE_QUEUE_ENTRY,
00246                                                 DeviceListEntry);
00247                 if (SortKey <= ReturnEntry->SortKey) break;
00248 
00249                 /* Try the next one */
00250                 NextEntry = NextEntry->Flink;
00251             }
00252         }
00253 
00254         /* We have an entry, remove it now */
00255         RemoveEntryList(&ReturnEntry->DeviceListEntry);
00256 
00257         /* Set it as non-inserted */
00258         ReturnEntry->Inserted = FALSE;
00259     }
00260 
00261     /* Release the lock */
00262     KiReleaseDeviceQueueLock(&DeviceLock);
00263 
00264     /* Return the entry */
00265     return ReturnEntry;
00266 }
00267 
00268 /*
00269  * @implemented
00270  */
00271 PKDEVICE_QUEUE_ENTRY
00272 NTAPI
00273 KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue,
00274                                IN ULONG SortKey)
00275 {
00276     PLIST_ENTRY NextEntry;
00277     PKDEVICE_QUEUE_ENTRY ReturnEntry;
00278     KLOCK_QUEUE_HANDLE DeviceLock;
00279     ASSERT_DEVICE_QUEUE(DeviceQueue);
00280 
00281     DPRINT("KeRemoveByKeyDeviceQueueIfBusy() DevQueue %p, SortKey 0x%x\n", DeviceQueue, SortKey);
00282 
00283     /* Lock the queue */
00284     KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
00285 
00286     /* Check if this is an empty or idle queue */
00287     if (!(DeviceQueue->Busy) || (IsListEmpty(&DeviceQueue->DeviceListHead)))
00288     {
00289         /* Set it to idle and return nothing*/
00290         DeviceQueue->Busy = FALSE;
00291         ReturnEntry = NULL;
00292     }
00293     else
00294     {
00295         /* If SortKey is greater than the last key, then return the first entry right away */
00296         NextEntry = &DeviceQueue->DeviceListHead;
00297         ReturnEntry = CONTAINING_RECORD(NextEntry->Blink,
00298                                         KDEVICE_QUEUE_ENTRY,
00299                                         DeviceListEntry);
00300 
00301         /* Check if we can just get the first entry */
00302         if (ReturnEntry->SortKey <= SortKey)
00303         {
00304             /* Get the first entry */
00305             ReturnEntry = CONTAINING_RECORD(NextEntry->Flink,
00306                                             KDEVICE_QUEUE_ENTRY,
00307                                             DeviceListEntry);
00308         }
00309         else
00310         {
00311             /* Loop the list */
00312             NextEntry = DeviceQueue->DeviceListHead.Flink;
00313             while (TRUE)
00314             {
00315                 /* Make sure we don't go beyond the end of the queue */
00316                 ASSERT(NextEntry != &DeviceQueue->DeviceListHead);
00317 
00318                 /* Get the next entry and check if the key is low enough */
00319                 ReturnEntry = CONTAINING_RECORD(NextEntry,
00320                                                 KDEVICE_QUEUE_ENTRY,
00321                                                 DeviceListEntry);
00322                 if (SortKey <= ReturnEntry->SortKey) break;
00323 
00324                 /* Try the next one */
00325                 NextEntry = NextEntry->Flink;
00326             }
00327         }
00328 
00329         /* We have an entry, remove it now */
00330         RemoveEntryList(&ReturnEntry->DeviceListEntry);
00331 
00332         /* Set it as non-inserted */
00333         ReturnEntry->Inserted = FALSE;
00334     }
00335 
00336     /* Release the lock */
00337     KiReleaseDeviceQueueLock(&DeviceLock);
00338 
00339     /* Return the entry */
00340     return ReturnEntry;
00341 }
00342 
00343 /*
00344  * @implemented
00345  */
00346 BOOLEAN
00347 NTAPI
00348 KeRemoveEntryDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
00349                          IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
00350 {
00351     BOOLEAN OldState;
00352     KLOCK_QUEUE_HANDLE DeviceLock;
00353     ASSERT_DEVICE_QUEUE(DeviceQueue);
00354 
00355     DPRINT("KeRemoveEntryDeviceQueue() DevQueue %p, Entry %p\n", DeviceQueue, DeviceQueueEntry);
00356 
00357     /* Lock the queue */
00358     KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
00359     ASSERT(DeviceQueue->Busy);
00360 
00361     /* Check the insertion state */
00362     OldState = DeviceQueueEntry->Inserted;
00363     if (OldState)
00364     {
00365         /* Remove it */
00366         DeviceQueueEntry->Inserted = FALSE;
00367         RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
00368     }
00369 
00370     /* Unlock and return old state */
00371     KiReleaseDeviceQueueLock(&DeviceLock);
00372     return OldState;
00373 }

Generated on Sun May 27 2012 04:37:31 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.