Kópia wikizrkadlo

Toto je zrkadlo wiki z pascal.chat. Úpravy, história a prihlásenie sú tam.

Main Loop Hooks/sk

English · Français · Slovenčina · 中文(中国) · 日本語

Prehľad problému

Potrebujete čakať kým nastane nejaká udalosť (v sokete alebo rúre ...), ale chcete to urobiť v základnom (GUI) vlákne a neblokovať GUI a tiež nechcete viacero vlákien? Riešenie tohoto problému je schopnosť pridať extra obsluhy, ktoré čakjú v hlavnej slučke udalostí.

Detaily riešenia

Pre poskytnutie tejto schopnosti boli do jednotky LCLIntf pridané dve funkcie:

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

Typ TWaitHandleEvent je deklarovaný v jednotke InterfaceBase ako:

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

AddEventHandler pridáva obsluhu čakajúcu v hlavnej slučke udalostí.

Keď je signalizovaná obsluha, potom je volaná procedúra zadaná v ACallback s parametrom AData, ktorý je poslaný pri registrovaní obsluhy udalosti, a príznakmi, ktoré sú špecifické pre OS. Príznaky, poslané do AddEventHandler, môžu byť upravené pomocou SetEventHandlerFlags. Handler (ukazovateľ) vrátený AddEventHandler musí byť poslaný do RemoveEventHandler pre zastavenie očakávania priradenej obsluhe.

RemoveEventHandler zastavuje očakávanie zadanej obluhy. RemoveEventHandler nastaví, pred ukončením, AHandler na nil. Jeho argumentom je ukazovateľ vrátený z AddEventHandler.

Windows

V aktuálnej implementácii nie je parameter AFlags v AddEventHandler použitý a AFlags v TWaitHandleEvent bude 0.

Win32 podporuje nasledujúce typy handle, v podstate veci podporované MsgWaitForMultipleObjects:

Gtk/Unix

Parameter AFlags v AddEventHandler udáva podmienky, za ktorých má byť signalizovaná obsluha, s možnýmy hodnotami dokuemntovanými v type GIOCondition v použití glib.

V spätnom volaní bude AFlags obsahovať podmienky vyššie odkazovaného typu GIOCondition, ktoré boli splnené.

Gtk/unix podporuje nasledujúce typy obsluhy:

Všimnite si, že Win32 nepodporuje sokety a rúry (prinajmenšom ich použitie je "odradzované" v MSDN). Návrh: použite WSAEventSelect na vytvorenie udalosti spojenej so soketom a pošlite obsluhu udalosti.

Rúry a ukončovanie procesu

Pre poskytnutie viac-platformného riešenia pre rúry (neveľmi podporované na Win32) a procesy (nie veľmi podporované na GTK/Unix) boli pridané ďalšie funkcie:

pascal
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;
pascal
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);

Keď proces končí, bude volaná zadaná obsluha udalosti. AInfo bude obsahovať ukončovací kód, ak AReason je cerExit, alebo (len Unix) ukončovací signál, ak AReason je cerSignal. Pre GTK/Unix, použite PID ako AHandle pre sledovanie. Interne, je nainštalovaný popisovač signálu pre pochopenie signálu SIGCHLD. Na Win32, je na čakanie ukončenia procesu použitý AddEventHandler.

Pre sledovanie rúry na prichádzajúce dáta, pošlite do AddPipeEventHandler popisovač súboru (unix) alebo handle konca čítania rúry, so zvolenou metódou obsluhy udalosti ako AEventHandler. Na GTK/Unix, je volaná AddEventHandler na čakanie prevádzky popisovača súboru. Na Win32, slučka správ vyprší každých 100 ms, na kontrolu všetkých čakaných rúr na dostupná dáta, ak sú dostupné dáta, je volaná obsluha udalosti.


From the Free Pascal wiki, page "Main Loop Hooks/sk", as it stood on 2008-01-02 after a change by Slavko, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Verzia 3, posledná zmena: WikiArchive .