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

iotimer.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/io/iocomp.c
00005  * PURPOSE:         I/O Wrappers for Executive Timers
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 /* GLOBALS *******************************************************************/
00016 
00017 /* Timer Database */
00018 KSPIN_LOCK IopTimerLock;
00019 LIST_ENTRY IopTimerQueueHead;
00020 
00021 /* Timer Firing */
00022 KDPC IopTimerDpc;
00023 KTIMER IopTimer;
00024 
00025 /* Keep count of how many timers we have */
00026 ULONG IopTimerCount = 0;
00027 
00028 /* PRIVATE FUNCTIONS *********************************************************/
00029 
00030 VOID
00031 NTAPI
00032 IopTimerDispatch(IN PKDPC Dpc,
00033                  IN PVOID DeferredContext,
00034                  IN PVOID SystemArgument1,
00035                  IN PVOID SystemArgument2)
00036 {
00037     KIRQL OldIrql;
00038     PLIST_ENTRY TimerEntry;
00039     PIO_TIMER Timer;
00040     ULONG i;
00041 
00042     /* Check if any Timers are actualyl enabled as of now */
00043     if (IopTimerCount)
00044     {
00045         /* Lock the Timers */
00046         KeAcquireSpinLock(&IopTimerLock, &OldIrql);
00047 
00048         /* Call the Timer Routine of each enabled Timer */
00049         for (TimerEntry = IopTimerQueueHead.Flink, i = IopTimerCount;
00050             (TimerEntry != &IopTimerQueueHead) && i;
00051             TimerEntry = TimerEntry->Flink)
00052         {
00053             /* Get the timer and check if it's enabled */
00054             Timer = CONTAINING_RECORD(TimerEntry, IO_TIMER, IoTimerList);
00055             if (Timer->TimerEnabled)
00056             {
00057                 /* Call the timer routine */
00058                 Timer->TimerRoutine(Timer->DeviceObject, Timer->Context);
00059                 i--;
00060             }
00061         }
00062 
00063         /* Unlock the Timers */
00064         KeReleaseSpinLock(&IopTimerLock, OldIrql);
00065     }
00066 }
00067 
00068 VOID
00069 NTAPI
00070 IopRemoveTimerFromTimerList(IN PIO_TIMER Timer)
00071 {
00072     KIRQL OldIrql;
00073 
00074     /* Lock Timers */
00075     KeAcquireSpinLock(&IopTimerLock, &OldIrql);
00076 
00077     /* Remove Timer from the List and Drop the Timer Count if Enabled */
00078     RemoveEntryList(&Timer->IoTimerList);
00079     if (Timer->TimerEnabled) IopTimerCount--;
00080 
00081     /* Unlock the Timers */
00082     KeReleaseSpinLock(&IopTimerLock, OldIrql);
00083 }
00084 
00085 /* PUBLIC FUNCTIONS **********************************************************/
00086 
00087 /*
00088  * @implemented
00089  */
00090 NTSTATUS
00091 NTAPI
00092 IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject,
00093                   IN PIO_TIMER_ROUTINE TimerRoutine,
00094                   IN PVOID Context)
00095 {
00096     PIO_TIMER IoTimer = DeviceObject->Timer;
00097     PAGED_CODE();
00098 
00099     /* Check if we don't have a timer yet */
00100     if (!IoTimer)
00101     {
00102         /* Allocate Timer */
00103         IoTimer = ExAllocatePoolWithTag(NonPagedPool,
00104                                         sizeof(IO_TIMER),
00105                                         TAG_IO_TIMER);
00106         if (!IoTimer) return STATUS_INSUFFICIENT_RESOURCES;
00107 
00108         /* Set up the Timer Structure */
00109         RtlZeroMemory(IoTimer, sizeof(IO_TIMER));
00110         IoTimer->Type = IO_TYPE_TIMER;
00111         IoTimer->DeviceObject = DeviceObject;
00112         DeviceObject->Timer = IoTimer;
00113     }
00114 
00115     /* Setup the timer routine and context */
00116     IoTimer->TimerRoutine = TimerRoutine;
00117     IoTimer->Context = Context;
00118 
00119     /* Add it to the Timer List */
00120     ExInterlockedInsertTailList(&IopTimerQueueHead,
00121                                 &IoTimer->IoTimerList,
00122                                 &IopTimerLock);
00123 
00124     /* Return Success */
00125     return STATUS_SUCCESS;
00126 }
00127 
00128 /*
00129  * @implemented
00130  */
00131 VOID
00132 NTAPI
00133 IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
00134 {
00135     KIRQL OldIrql;
00136     PIO_TIMER IoTimer = DeviceObject->Timer;
00137 
00138     /* Make sure the device isn't unloading */
00139     if (!(((PEXTENDED_DEVOBJ_EXTENSION)(DeviceObject->DeviceObjectExtension))->
00140             ExtensionFlags & (DOE_UNLOAD_PENDING |
00141                               DOE_DELETE_PENDING |
00142                               DOE_REMOVE_PENDING |
00143                               DOE_REMOVE_PROCESSED)))
00144     {
00145         /* Lock Timers */
00146         KeAcquireSpinLock(&IopTimerLock, &OldIrql);
00147 
00148         /* Check if the timer isn't already enabled */
00149         if (!IoTimer->TimerEnabled)
00150         {
00151             /* Enable it and increase the timer count */
00152             IoTimer->TimerEnabled = TRUE;
00153             IopTimerCount++;
00154         }
00155 
00156         /* Unlock Timers */
00157         KeReleaseSpinLock(&IopTimerLock, OldIrql);
00158     }
00159 }
00160 
00161 /*
00162  * @implemented
00163  */
00164 VOID
00165 NTAPI
00166 IoStopTimer(PDEVICE_OBJECT DeviceObject)
00167 {
00168     KIRQL OldIrql;
00169     PIO_TIMER IoTimer = DeviceObject->Timer;
00170 
00171     /* Lock Timers */
00172     KeAcquireSpinLock(&IopTimerLock, &OldIrql);
00173 
00174     /* Check if the timer is enabled */
00175     if (IoTimer->TimerEnabled)
00176     {
00177         /* Disable it and decrease the timer count */
00178         IoTimer->TimerEnabled = FALSE;
00179         IopTimerCount--;
00180     }
00181 
00182     /* Unlock Timers */
00183     KeReleaseSpinLock(&IopTimerLock, OldIrql);
00184 }
00185 
00186 /* EOF */

Generated on Wed May 23 2012 04:35:09 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.