Main Loop Hooks/sk: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Main Loop Hooks/sk
| Old | New | Line | |
|---|---|---|---|
| 1 | + | ## Prehľad problému | |
| 2 | + | ||
| 3 | + | 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í. | |
| 4 | + | ||
| 5 | + | ## Detaily riešenia | |
| 6 | + | ||
| 7 | + | Pre poskytnutie tejto schopnosti boli do jednotky [[doc:lcl/lclintf|LCLIntf]] pridané dve funkcie: | |
| 8 | + | ||
| 9 | + | `AddEventHandler(AHandle: THandle; AFlags: dword; `\ | |
| 10 | + | ` AEventHandler: TWaitHandleEvent; AData: PtrInt): PEventHandler;`\ | |
| 11 | + | `RemoveEventHandler(var AHandler: PEventHandler);`\ | |
| 12 | + | `SetEventHandlerFlags(AHandler: PEventHandler; NewFlags: dword);` | |
| 13 | + | ||
| 14 | + | Typ [[doc:lcl/interfacebase/twaithandleevent.html|TWaitHandleEvent]] je deklarovaný v jednotke **InterfaceBase** ako: | |
| 15 | + | ||
| 16 | + | ` TWaitHandleEvent = procedure(AData: PtrInt; AFlags: dword) of object;` | |
| 17 | + | ||
| 18 | + | [[doc:lcl/lclintf/addeventhandler.html|AddEventHandler]] pridáva obsluhu čakajúcu v hlavnej slučke udalostí. | |
| 19 | + | ||
| 20 | + | 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. | |
| 21 | + | ||
| 22 | + | [[doc:lcl/lclintf/removeeventhandler.html|RemoveEventHandler]] zastavuje očakávanie zadanej obluhy. **RemoveEventHandler** nastaví, pred ukončením, **AHandler** na nil. Jeho argumentom je ukazovateľ vrátený z **AddEventHandler**. | |
| 23 | + | ||
| 24 | + | ### Windows | |
| 25 | + | ||
| 26 | + | V aktuálnej implementácii nie je parameter **AFlags** v **AddEventHandler** použitý a **AFlags** v **TWaitHandleEvent** bude 0. | |
| 27 | + | ||
| 28 | + | Win32 podporuje nasledujúce typy handle, v podstate veci podporované MsgWaitForMultipleObjects: | |
| 29 | + | ||
| 30 | + | - oznamovania zmeny (pre súbory a adresáre) | |
| 31 | + | - konzolový vstup | |
| 32 | + | - udalosti: signalizované WinAPI funkciou SetEvent | |
| 33 | + | - mutexy: signalizované keď ich nikto nevlastní | |
| 34 | + | - procesy: signalizované keď sú skončené | |
| 35 | + | - semfóry: signalizované keď je ich počet väčší ako nula | |
| 36 | + | - vlákna: signalizované keď sú skončené | |
| 37 | + | - časovače: signalizované keď vyprší, viz SetWaitableTimer | |
| 38 | + | ||
| 39 | + | ### Gtk/Unix | |
| 40 | + | ||
| 41 | + | 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](http://developer.gimp.org/api/2.0/glib/glib-IO-Channels.html#GIOCondition). | |
| 42 | + | ||
| 43 | + | V spätnom volaní bude **AFlags** obsahovať podmienky vyššie odkazovaného typu **GIOCondition**, ktoré boli splnené. | |
| 44 | + | ||
| 45 | + | Gtk/unix podporuje nasledujúce typy obsluhy: | |
| 46 | + | ||
| 47 | + | - súbory | |
| 48 | + | - sokety | |
| 49 | + | - rúry | |
| 50 | + | ||
| 51 | + | 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. | |
| 52 | + | ||
| 53 | + | ### Rúry a ukončovanie procesu | |
| 54 | + | ||
| 55 | + | 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: | |
| 56 | + | ||
| 57 | + | `TChildExitReason = (cerExit, cerSignal);`\ | |
| 58 | + | `TPipeReason = (prDataAvailable, prBroken, prCanWrite);`\ | |
| 59 | + | `TPipeReasons = set of TPipeReason;`\ | |
| 60 | + | \ | |
| 61 | + | `TChildExitEvent = procedure(AData: PtrInt; AReason: TChildExitReason; AInfo: dword) of object;`\ | |
| 62 | + | `TPipeEvent = procedure(AData: PtrInt; AReasons: TPipeReasons) of object;` | |
| 63 | + | ||
| 64 | + | `function AddProcessEventHandler(AHandle: THandle; `\ | |
| 65 | + | ` AEventHandler: TChildExitEvent; AData: PtrInt): PProcessEventHandler;`\ | |
| 66 | + | `procedure RemoveProcessEventHandler(var AHandler: PProcessEventHandler);`\ | |
| 67 | + | \ | |
| 68 | + | `function AddPipeEventHandler(AHandle: THandle; `\ | |
| 69 | + | ` AEventHandler: TPipeEvent; AData: PtrInt): PPipeEventHandler;`\ | |
| 70 | + | `procedure RemovePipeEventHandler(var AHandler: PPipeEventHandler);` | |
| 71 | + | ||
| 72 | + | 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**. | |
| 73 | + | ||
| 74 | + | 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. | |
| 75 | + | ||
| 76 | + | --- | |
| 77 | + | *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](/wiki-contact).* |
