Les APC sont exécutées jusqu'à ce que la file d'attente soit vide. lorsque votre code renvoyé par APC - vérification du système sont un autre APC inséré - si oui - suivant APC est exécuté, jusqu'à ce que plus aucun APC inséré dans le fil. après cette SleepEx
(ou tout autre api alertable d'attente) commande de retour pour vous
l'APC exécuté de manière suivante - lorsque vous appelez certains api (SleepEx
, MsgWaitForMultipleObjectsEx
, WaitForSingleObjectEx
, WaitForMultipleObjectsEx
.. avec jeu de paramètres bAlertable de la fonction TRUE) vérification du noyau sont APC inséré dans l'objet thread. si oui - le noyau copie le contexte du thread en mode utilisateur dans la pile, remplace le contexte du thread (l'adresse de retour du mode utilisateur est définie sur ntdll.KiUserApcDispatcher
) et renvoie. comme le code de retour ne retourne pas d'où il est entré au noyau (dans le cas SleepEx
c'est ZwDelayExecution
qui appelle en interne) mais au KiUserApcDispatcher
. cette API exécute APC puis appelle le ZwContinue
. ce api déclaré:
NTSYSAPI NTSTATUS NTAPI ZwContinue(PCONTEXT Context, BOOLEAN TestAlert);
en place Contexte utilisé enregistré dans la pile contexte de fil, pour le retour au point, à partir de laquelle api alertable a été appelé, et TestAlert
indique si doit vérifier apc supplémentaire inséré. si appeler ZwContinue
avec TestAlert == FALSE
système ne sera plus vérifier pour APC dans la file d'attente de threads jusqu'à ce que vous n'appelez pas vous-même SleepEx
ou autre api - sera exactement 1 APC exécuté. mais dans KiUserApcDispatcher
TestAlert
à hardcoded TRUE
- vous pouvez facilement regarder vous-même, si comprendre le code de montage (le KiUserApcDispatcher
est minuscule)
Il est inconnaissable. Le thread qui appelle QueueUserApc() n'a aucune idée si le thread alertable a repris. Que le fil d'alerte fonctionne ou non dans la file d'attente avant de reprendre n'a plus d'importance. –
@HansPassant Ma question n'est pas du point de vue de QueueUserApc, mais comment fonctionne SleepEx. –
@HansPassant - vous vous trompez. ceci est probablement non documenté, mais on sait exactement - quand le retour de thread de * APC * - vérification du système est APC supplémentaire inséré dans le fil. et si oui, exécutez-le. donc ce sera en boucle, jusqu'à ce que plus aucun APC dans le fil – RbMm