Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Elk stuurprogramma dat gebruikmaakt van een gebeurtenisobject, moet KeInitializeEvent, IoCreateNotificationEvent of IoCreateSynchronizationEvent aanroepen voordat het stuurprogramma wacht, instelt, wist of de gebeurtenis opnieuw instelt. In de volgende afbeelding ziet u hoe een stuurprogramma met een thread een gebeurtenisobject kan gebruiken voor synchronisatie.
Zoals de vorige afbeelding laat zien, moet een dergelijk stuurprogramma de opslag voor het gebeurtenisobject voorzien, dat resident moet zijn. Het stuurprogramma kan de apparaatextensie van een apparaatobject dat door het stuurprogramma is gemaakt, de controllerextensie gebruiken als deze gebruikmaakt van een controllerobject, of een niet-gepaginade pool die door het stuurprogramma is toegewezen.
Wanneer het stuurprogramma KeInitializeEvent aanroept, moet deze een aanwijzer doorgeven aan de residente opslag van het stuurprogramma voor het gebeurtenisobject. Bovendien moet de aanroeper de initiële status (gesignaleerd of niet gesignaleerd) voor het gebeurtenisobject opgeven. De beller moet ook het gebeurtenistype opgeven. Dit kan een van de volgende zijn:
SynchronizationEvent
Wanneer een synchronisatiegebeurtenis is ingesteld op de status Gesignaleerd, wordt één thread die wacht totdat de gebeurtenis opnieuw wordt ingesteld op Not-Signaled in aanmerking komt voor uitvoering en wordt de status van de gebeurtenis automatisch opnieuw ingesteld op Not-Signaled.
Dit type gebeurtenis wordt soms een autoclearing-gebeurtenis genoemd, omdat de gesignaleerde status automatisch wordt gereset elke keer wanneer een wachttijd is vervuld.
NotificationEvent
Wanneer een meldingsgebeurtenis is ingesteld op de status Gesignaleerd, blijven alle threads die wachten totdat de gebeurtenis opnieuw wordt ingesteld op Not-Signaled in aanmerking komen voor uitvoering en blijft de gebeurtenis in de status Gesignaleerd totdat een expliciete reset naar Not-Signaled plaatsvindt: dat wil gezegd, er is een aanroep naar KeReadEvent of KeResetEvent met de opgegeven gebeurtenisaanwijzer .
Enkele apparaat- of tussenliggende stuurprogramma's hebben een stuurprogramma-gewijde thread, laat staan een reeks threads die hun operaties kunnen synchroniseren door te wachten op een gebeurtenis die een gedeelde resource beschermt.
De meeste stuurprogramma's die gebeurtenisobjecten gebruiken om te wachten op de voltooiing van een I/O-bewerking, stellen de Type in op NotificationEvent wanneer ze KeInitializeEvent aanroepen. Een gebeurtenisobject dat is ingesteld voor IRP's die een driver maakt met IoBuildSynchronousFsdRequest of IoBuildDeviceIoControlRequest, wordt bijna altijd geïnitialiseerd als een NotificationEvent omdat de aanroeper op de gebeurtenis wacht ter kennisgeving dat de aanvraag is voldaan door een of meerdere lagere drivers.
Nadat het stuurprogramma zichzelf heeft geïnitialiseerd, kunnen de door het stuurprogramma toegewezen thread, indien aanwezig, en andere routines hun bewerkingen op de gebeurtenis synchroniseren. Een stuurprogramma met een thread die de wachtrij van IRP's beheert, zoals het stuurprogramma voor de systeemdiskettecontroller, kan bijvoorbeeld de verwerking van IRP's synchroniseren bij een gebeurtenis, zoals weergegeven in de vorige afbeelding.
De thread, die een IRP uit de wachtrij heeft gehaald voor verwerking op het apparaat, roept KeWaitForSingleObject aan met een pointer naar de opslag geleverd door het stuurprogramma voor het geïnitialiseerde gebeurtenisobject.
Andere stuurprogrammaroutines voeren de I/O-bewerkingen uit die nodig zijn om te voldoen aan het IRP en, wanneer deze bewerkingen zijn voltooid, roept de DpcForIsr-routinekeSetEvent aan met een aanwijzer naar het gebeurtenisobject, een door het stuurprogramma bepaald prioriteitsverhoging voor de thread (Increment, zoals wordt weergegeven in de vorige afbeelding) en een Booleaanse wachttijd ingesteld op FALSE. Door KeSetEvent aan te roepen, wordt het gebeurtenisobject ingesteld op de status Signaled, waardoor de status van de wachtthread wordt gewijzigd in gereed.
De kernel verzendt de thread voor uitvoering zodra er een processor beschikbaar is: er is momenteel geen andere thread met een hogere prioriteit in de status Gereed en er zijn geen kernelmodusroutines die op een hogere IRQL moeten worden uitgevoerd.
De thread kan nu de IRP voltooien als de DpcForIsr nog niet IoCompleteRequest met de IRP heeft aangeroepen, en kan vervolgens een andere IRP uit de wachtrij halen voor verwerking op het apparaat.
Het aanroepen van KeSetEvent met de wachtparameter ingesteld op TRUE geeft aan dat de beller onmiddellijk een KeWaitForSingleObject - of KeWaitForMultipleObjects-ondersteuningsroutine wil aanroepen bij terugkeer van KeSetEvent.
Houd rekening met de volgende richtlijnen voor het instellen van dewachtparameter opKeSetEvent:
Een pageable thread of driver routine die werkt op IRQL < DISPATCH_LEVEL mag nooit KeSetEvent aanroepen met de Wait-parameter ingesteld op TRUE. Een dergelijke aanroep veroorzaakt een fatale paginafout als de beller tussen de aanroepen aan KeSetEvent en KeWaitForSingleObject of KeWaitForMultipleObjects wordt uitgepaget.
Elke standaard driverroutine die wordt uitgevoerd op IRQL = DISPATCH_LEVEL kan niet wachten op een niet-nul interval op dispatcherobjecten zonder het systeem te laten crashen. Een dergelijke routine kan KeSetEvent echter aanroepen tijdens het uitvoeren op een IRQL kleiner dan of gelijk aan DISPATCH_LEVEL.
Zie Hardwareprioriteiten beherenvoor een overzicht van de IRQLs waarop standaardstuurprogrammaroutines worden uitgevoerd.
KeResetEvent retourneert de vorige status van een bepaalde gebeurtenis: of deze is ingesteld op Signaled of niet wanneer de aanroep naar KeResetEvent heeft plaatsgevonden. Ke ClearEvent stelt simpelweg de status van de opgegeven gebeurtenis in op Not-Signaled.
Houd rekening met de volgende richtlijn voor het aanroepen van de voorafgaande ondersteuningsroutines:
Voor betere prestaties moet elk stuurprogramma KeClearEvent aanroepen, tenzij de beller de informatie nodig heeft die door KeResetEvent wordt geretourneerd om te bepalen wat er vervolgens moet worden uitgevoerd.