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