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