Difference between revisions of "Main Loop Hooks/fr"

From Lazarus wiki
Jump to navigationJump to search
(New page: {{Main Loop Hooks}} == Problem statement == You need to wait for some event (on socket or pipe or ...) to happen, but you want to do this in the main (GUI) thread and do not want to blo...)
 
 
(9 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{Main Loop Hooks}}
 
{{Main Loop Hooks}}
  
== Problem statement ==  
+
== Enoncé du problème ==  
  
You need to wait for some event (on socket or pipe or ...) to happen, but you want to do this in the main (GUI) thread and do not want to block the GUI and also you do not want multi-threading. Solution to this problem is the ability to add extra "handles" to be watched in the main event loop.
+
Vous devez attendre un événement (sur le socket[http://www.dicofr.com/cgi-bin/n.pl/dicofr/definition/20010101004807] ou pipe ou ...) qui arrive, mais vous voulez faire cela dans le processus principal (GUI) et vous ne voulez pas bloquer le GUI et aussi vous ne voulez pas faire du multi-threading. La solution à ce problème est la possibilité d'ajouter des "handles" [http://www.dicofr.com/cgi-bin/n.pl/dicofr/definition/20010101002342] supplémentaires pour être observés dans la boucle d'événement principale.
  
== Solution details ==
+
== Les détails de la Solution ==
  
In unit [[doc:lcl/lclintf|LCLIntf]] two functions have been added to provide for this functionality, they are:
+
Dans l'unité [[doc:lcl/lclintf|LCLIntf]] deux fonctions ont été ajoutées pour tenir compte de cette fonctionnalité, ce sont :
  
 
  AddEventHandler(AHandle: THandle; AFlags: dword;  
 
  AddEventHandler(AHandle: THandle; AFlags: dword;  
Line 14: Line 14:
 
  SetEventHandlerFlags(AHandler: PEventHandler; NewFlags: dword);
 
  SetEventHandlerFlags(AHandler: PEventHandler; NewFlags: dword);
  
The [[doc:lcl/interfacebase/twaithandleevent.html | TWaitHandleEvent]] type is declared in unit InterfaceBase as:
+
Le [[doc:lcl/interfacebase/twaithandleevent.html | TWaitHandleEvent]] est déclaré dans l'unité InterfaceBase comme :
  
 
   TWaitHandleEvent = procedure(AData: PtrInt; AFlags: dword) of object;
 
   TWaitHandleEvent = procedure(AData: PtrInt; AFlags: dword) of object;
  
[[doc:lcl/lclintf/addeventhandler.html | AddEventHandler]] adds a handle to be watched to the main event loop.  
+
[[doc:lcl/lclintf/addeventhandler.html | AddEventHandler]] ajoute un handle pour être observé dans la boucle d'évênement principale.  
When the handle is "signalled", then the procedure specified in ACallback will be called with as a parameter the AData that was passed when registering the event handler, and any Flags, which are OS specific. The flags passed to AddEventHandler can be modified using SetEventHandlerFlags. The returned handler (a pointer) by AddEventHandler should be passed to RemoveEventHandler to stop watching the associated handle.
+
Quand le handle est  "signalé ", alors la procédure indiqué dans ACallback sera appellé avec comme paramètre AData qui était passé lors de l'enregistrement du traiteur d'évênement, et tous drapeaux , qui dont spécifiques au système d'exploitation. Le drapeau passés à  AddEventHandler peut être modifié en utilisants le SetEventHandlerFlags. Le handler retourné (un pointeur) par AddEventHandler devrait être passé à  RemoveEventHandler pour cesser d'observer l'handle associée .
  
[[doc:lcl/lclintf/removeeventhandler.html | RemoveEventHandler]] stops watching the specified handle. RemoveEventHandler will set AHandler to nil before returning. Its argument is a pointer returned by AddEventHandler.
+
[[doc:lcl/lclintf/removeeventhandler.html | RemoveEventHandler]] arrête d'observer l'handle spécifié. RemoveEventHandler fixera AHandler à nil avant le renvoi . Son argument est un pointeur retourné par AddEventHandler.
  
 
=== Windows ===
 
=== Windows ===
  
The AFlags parameter in AddEventHandler is unused, and the AFlags in TWaitHandleEvent will be 0, in the current implementation.
+
Le paramètre AFlags dans AddEventHandler n'est pas utilisé, et le AFlags dans TWaitHandleEvent a pour valeur dans l'implémentation actuelle.
  
Win32 supports the following handle types, basically the things supported by MsgWaitForMultipleObjects:
+
Win32 supportes les types de handeles suivants, basiquement les choses supportées par MsgWaitForMultipleObjects:
* change notifications (for files and directories)
+
* notifications de changement (pour les fichiers et dossiers)
* console input
+
* entrées de console (console input)
* events: signalled with SetEvent winapi function
+
* events: signalés avec la fonction winapi SetEvent
* mutexes: signalled when it is not owned anymore
+
* mutexes: signalés quand il n 'est plus possédé par quoi que ce soit
* processes: signalled when they terminate
+
* processes: signalés quand ils sont terminés
* semaphore: signalled when it's ''count'' is greater than zero
+
* semaphore: signalés quand son ''count'' est supérieur à 0
* threads: signalled when they terminate
+
* threads: signalés quand ils sont terminés
* timers: signalled when expired, see SetWaitableTimer
+
* timers: signalés quand ils expirent, voir SetWaitableTimer
  
 
=== Gtk/Unix ===  
 
=== Gtk/Unix ===  
  
The AFlags parameter in AddEventHandler specifies the condition in which the handle should be signalled, with the possible values being the ones documented in the GIOCondition type in the [http://developer.gimp.org/api/2.0/glib/glib-IO-Channels.html#GIOCondition glib] reference.
+
Le paramètre AFlags de AddEventHandler spécifie la condition dans laquelle le handle devrait être signalé, avec pour valeurs possibles celles documentées dans le type GIOCondition dans la référence [http://developer.gimp.org/api/2.0/glib/glib-IO-Channels.html#GIOCondition glib].
  
In the callback, the AFlags will contain the condition, of the above referenced GIOCondition type, that was satisfied.
+
Dans le callback, AFlags contiendra la condition, comme référencée dans le type GIOCondition vu ci-dessus, qui doit être satistfaite.
  
Gtk/unix supports the following handle types:
+
Gtk/unix supporte les types de handles suivants:
* files
+
* fichiers
 
* sockets
 
* sockets
 
* pipes
 
* pipes
  
Note that win32 does not support sockets or pipes (at least, their use is "discouraged" by MSDN). Suggestion: use WSAEventSelect to create an event associated with a socket and pass the event handle.
+
Notez que win32 ne supporte pas les sockets ou les pipes (du moins, leur usage est "découragé" par MSDN). Suggestion: utiliser WSAEventSelect pour créer un évenement associé à une socket et passer le handle d'évenement.
  
=== Pipes and Process Termination ===
+
=== Pipes et Terminaison de Processus ===
  
To provide a cross-platform solution for pipes (not well supported on win32) and processes (not well supported on gtk/unix) additional functions have been added:
+
Pour offrir une solution cross-platform pour les pipes (mal supportés sous win32) et les processus (mal supportés sous gtk/unix) des fonctions additionnelles ont été ajoutées:
  
 
  TChildExitReason = (cerExit, cerSignal);
 
  TChildExitReason = (cerExit, cerSignal);
Line 69: Line 69:
 
  procedure RemovePipeEventHandler(var AHandler: PPipeEventHandler);
 
  procedure RemovePipeEventHandler(var AHandler: PPipeEventHandler);
  
When a process terminates the event handler specified will be called. AInfo will contain the exit code if AReason is cerExit, or (on unix only) the termination signal if AReason is cerSignal. For gtk/unix, use the PID to watch as AHandle. Internally, a signal handler is installed to catch the SIGCHLD signal. On win32, AddEventHandler is used to watch process termination.
+
Quand un processus se termine le handler d'événement spécifié sera appelé. AInfo contiendra le code de sortie si AReason est cerExit, ou (sous unix seulement) le signal de terminaison si AReason est cerSignal. Pour gtk/unix, utilisez le PID pour surveiller en tant que AHandle. En interne, un handler de signal est installé pour surveiller le signal SIGCHLD. Sous win32, AddEventHandler est utilisé pour surveiller la terminaison de processus.
  
To watch a pipe for incoming data, pass the file descriptor (unix) or the pipe read-end handle to AddPipeEventHandler with a custom chosen event handler method as AEventHandler. On gtk/unix, AddEventHandler is called to watch the file descriptor for traffic. On win32, the message loop will timeout every 100 msecs to check all watched pipes for available data; if data is available, the event handler is called.
+
Pour surveiller les données entrantes d'un pipe, passez le descripteur de fichier (unix) ou le handle de la partie lecture du pipe à AddPipeEventHandler avec une méthode de handler d'événement personnalisé choisi en tant que AEventHandler. Sous gtk/unix, AddEventHandler est appelé pour surveiller le traffic sur le descripteur de fichier. Sous win32, la boucle de message fait un timeout toutes les 100 msecs pour vérifier s'il y a des données disponibles sur tous les pipes surveillés; si des données sont disponibles, le handler d'événement est appelé.

Latest revision as of 12:01, 19 June 2008

English (en) français (fr) 日本語 (ja) slovenčina (sk) 中文(中国大陆)‎ (zh_CN)

Enoncé du problème

Vous devez attendre un événement (sur le socket[1] ou pipe ou ...) qui arrive, mais vous voulez faire cela dans le processus principal (GUI) et vous ne voulez pas bloquer le GUI et aussi vous ne voulez pas faire du multi-threading. La solution à ce problème est la possibilité d'ajouter des "handles" [2] supplémentaires pour être observés dans la boucle d'événement principale.

Les détails de la Solution

Dans l'unité LCLIntf deux fonctions ont été ajoutées pour tenir compte de cette fonctionnalité, ce sont :

AddEventHandler(AHandle: THandle; AFlags: dword; 
    AEventHandler: TWaitHandleEvent; AData: PtrInt): PEventHandler;
RemoveEventHandler(var AHandler: PEventHandler);
SetEventHandlerFlags(AHandler: PEventHandler; NewFlags: dword);

Le TWaitHandleEvent est déclaré dans l'unité InterfaceBase comme :

 TWaitHandleEvent = procedure(AData: PtrInt; AFlags: dword) of object;

AddEventHandler ajoute un handle pour être observé dans la boucle d'évênement principale. Quand le handle est "signalé ", alors la procédure indiqué dans ACallback sera appellé avec comme paramètre AData qui était passé lors de l'enregistrement du traiteur d'évênement, et tous drapeaux , qui dont spécifiques au système d'exploitation. Le drapeau passés à AddEventHandler peut être modifié en utilisants le SetEventHandlerFlags. Le handler retourné (un pointeur) par AddEventHandler devrait être passé à RemoveEventHandler pour cesser d'observer l'handle associée .

RemoveEventHandler arrête d'observer l'handle spécifié. RemoveEventHandler fixera AHandler à nil avant le renvoi . Son argument est un pointeur retourné par AddEventHandler.

Windows

Le paramètre AFlags dans AddEventHandler n'est pas utilisé, et le AFlags dans TWaitHandleEvent a pour valeur dans l'implémentation actuelle.

Win32 supportes les types de handeles suivants, basiquement les choses supportées par MsgWaitForMultipleObjects:

  • notifications de changement (pour les fichiers et dossiers)
  • entrées de console (console input)
  • events: signalés avec la fonction winapi SetEvent
  • mutexes: signalés quand il n 'est plus possédé par quoi que ce soit
  • processes: signalés quand ils sont terminés
  • semaphore: signalés quand son count est supérieur à 0
  • threads: signalés quand ils sont terminés
  • timers: signalés quand ils expirent, voir SetWaitableTimer

Gtk/Unix

Le paramètre AFlags de AddEventHandler spécifie la condition dans laquelle le handle devrait être signalé, avec pour valeurs possibles celles documentées dans le type GIOCondition dans la référence glib.

Dans le callback, AFlags contiendra la condition, comme référencée dans le type GIOCondition vu ci-dessus, qui doit être satistfaite.

Gtk/unix supporte les types de handles suivants:

  • fichiers
  • sockets
  • pipes

Notez que win32 ne supporte pas les sockets ou les pipes (du moins, leur usage est "découragé" par MSDN). Suggestion: utiliser WSAEventSelect pour créer un évenement associé à une socket et passer le handle d'évenement.

Pipes et Terminaison de Processus

Pour offrir une solution cross-platform pour les pipes (mal supportés sous win32) et les processus (mal supportés sous gtk/unix) des fonctions additionnelles ont été ajoutées:

TChildExitReason = (cerExit, cerSignal);
TPipeReason = (prDataAvailable, prBroken, prCanWrite);
TPipeReasons = set of TPipeReason;

TChildExitEvent = procedure(AData: PtrInt; AReason: TChildExitReason; AInfo: dword) of object;
TPipeEvent = procedure(AData: PtrInt; AReasons: TPipeReasons) of object;
function  AddProcessEventHandler(AHandle: THandle; 
    AEventHandler: TChildExitEvent; AData: PtrInt): PProcessEventHandler;
procedure RemoveProcessEventHandler(var AHandler: PProcessEventHandler);

function  AddPipeEventHandler(AHandle: THandle; 
    AEventHandler: TPipeEvent; AData: PtrInt): PPipeEventHandler;
procedure RemovePipeEventHandler(var AHandler: PPipeEventHandler);

Quand un processus se termine le handler d'événement spécifié sera appelé. AInfo contiendra le code de sortie si AReason est cerExit, ou (sous unix seulement) le signal de terminaison si AReason est cerSignal. Pour gtk/unix, utilisez le PID pour surveiller en tant que AHandle. En interne, un handler de signal est installé pour surveiller le signal SIGCHLD. Sous win32, AddEventHandler est utilisé pour surveiller la terminaison de processus.

Pour surveiller les données entrantes d'un pipe, passez le descripteur de fichier (unix) ou le handle de la partie lecture du pipe à AddPipeEventHandler avec une méthode de handler d'événement personnalisé choisi en tant que AEventHandler. Sous gtk/unix, AddEventHandler est appelé pour surveiller le traffic sur le descripteur de fichier. Sous win32, la boucle de message fait un timeout toutes les 100 msecs pour vérifier s'il y a des données disponibles sur tous les pipes surveillés; si des données sont disponibles, le handler d'événement est appelé.