home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #7 / amigamamagazinepolishissue1998.iso / magazyn_amiga / 0896 / 028_porty < prev    next >
Text File  |  1998-03-26  |  11KB  |  251 lines

  1.  
  2. exec.library
  3. ------------
  4.  
  5. PORTY
  6.  
  7. <lead>Moûe to pojëcie obiîo Ci sië juû o uszy. Moûe nawet wiesz,
  8. czym sâ porty i jak z nich korzystaê? Jeôli tak, to nie musisz
  9. czytaê tego artykuîu. Jednakûe jeôli port kojarzy Ci sië
  10. wyîâcznie z zacumowanymi do nadgniîych sîupów i obijajâcymi sië o
  11. burty kutrami, gdzie powietrze jest wypeînione sîonym zapachem
  12. morza i bardziej juû przykrym odorem nadgniîych ryb, to gorâco Ci
  13. polecam lekturë poniûszego tekstu.
  14.  
  15. <a>Cromax/Alchemy
  16.  
  17. <txt>Port -- ten zwykîy, gdzie moûna znaleúê snujâcych sië
  18. marynarzy i gotowe na wszystko kobiety, istnieje, ûeby mogîy do
  19. niego zawijaê i odpîywaê z niego statki. Identycznie rzecz sië ma
  20. z portami z Execa. Jedynâ róûnicâ jest brak zepsutego powietrza i
  21. sîonej wody, statki zaô sâ zastâpione wpîywajâcymi (lub
  22. wychodzâcymi) wiadomoôciami (a gdzie te kobiety? -- red.).
  23.  
  24. Port -- teraz juû ten execowy -- to po prostu kawaîek pamiëci, a
  25. precyzujâc, pewna struktura. Jeôli teraz znamy adres poczâtku tej
  26. struktury w pamiëci, czyli innymi sîowy adres tego portu, moûemy
  27. wysîaê do niego wiadomoôê (dalej bëdë uûywaî angielskiego
  28. okreôlenia message). Moûemy teû zatrzymaê nasz program i
  29. poczekaê, aû wpîynie do niego jakiô komunikat (czyli po angielsku
  30. message). Kiedy taki message przybëdzie, naleûy go odebraê,
  31. odczytaê, odpowiednio zinterpretowaê, ewentualnie wykonaê jakieô
  32. dziaîanie i odpowiedzieê (czësto koniecznie!) nadawcy, ûe juû
  33. uporaliômy sië z komunikatem. Na ogóî mechanizm czekania na
  34. wiadomoôê, jej odbierania, przetwarzania itd. jest standardowy.
  35.  
  36. Tak jak wyûej wspomniaîem -- najpierw korzystamy z procedury,
  37. która zatrzymuje nasz program i czeka na wiadomoôê. Kiedy
  38. komunikat dotrze do portu, procedura zwróci adres pierwszego
  39. dostëpnego komunikatu (patrz poniûej opis struktury Message).
  40. Wtedy my odczytujemy wiadomoôê i na podstawie zawartych w niej
  41. danych wykonujemy odpowiednie dziaîanie. Kiedy skoïczymy,
  42. odpowiadamy nadawcy, który wysîaî nam wiadomoôê (w strukturze
  43. Message na ogóî znajduje sië adres portu nadajâcego komunikat).
  44. Czasami moûna zmieniê kolejnoôê tych dziaîaï, tzn. najpierw
  45. odpowiedzieê nadawcy, a dopiero potem zabraê sië do odczytywania
  46. wiadomoôci. W tym wypadku jednak musimy byê caîkowicie pewni, ûe
  47. taka zamiana jest dozwolona (wyjaônienie póúniej). Nie zawsze
  48. moûna jej dokonaê. Natomiast jeûeli zamierzamy wysîaê komunikat,
  49. musimy znaê adres portu, do którego message ma dotrzeê;
  50. powinniômy takûe umieôciê w naszej wiadomoôci adres naszego portu
  51. (choê to nie zawsze jest konieczne), ûeby odbiorca wiedziaî, komu
  52. odpowiedzieê. Na dobrâ sprawë, to mniej wiëcej wîaônie tak
  53. wyglâdajâ porty i komunikacja miëdzy nimi -- oczekiwanie na
  54. wiadomoôci oraz ich wysyîanie.
  55.  
  56. Poprzedni akapit byî bardzo ogólnym wprowadzeniem. W tym
  57. znajdziesz wiëcej szczegóîów. Do obsîugi portów oraz systemu
  58. komunikacji przewidzianych jest zaledwie kilka procedur (plus
  59. dwie nowe w systemach +2.0) z biblioteki exec.library. Sâ to:
  60.  
  61. <l>    _LVOWait            Equ    -318
  62.  
  63.     _LVOAllocSignal        Equ -330
  64.  
  65.     _LVOFreeSignal        Eqi -336
  66.  
  67.     _LVOAddPort            Equ    -354
  68.  
  69.     _LVORemPort            Equ    -360
  70.  
  71.     _LVOPutMsg            Equ    -366
  72.  
  73.     _LVOGetMsg            Equ    -372
  74.  
  75.     _LVOReplyMsg        Equ    -378
  76.  
  77.     _LVOWaitPort        Equ    -384
  78.  
  79.     _LVOFindPort        Equ    -390
  80.  
  81.     _LVOCreateMsgPort    Equ    -666    ; V36 (2.0)
  82.  
  83.     _LVODeleteMsgPort    Equ    -672    ; V36 (2.0)
  84.  
  85. <txt>Z pewnych powodów trzy pierwsze funkcje opiszë na samym
  86. koïcu. Zanim jednak zacznë opisywaê dwie nastëpne procedury,
  87. muszë wspomnieê o dwóch rodzajach portów, a mianowicie o portach
  88. publicznych (public ports) i prywatnych. Port publiczny to taki,
  89. którego adres zostaje umieszczony na systemowej liôcie (nawiasem
  90. mówiâc, dwukierunkowej, czyli tzw. double-linked) portów
  91. publicznych. Mogâ mieê do niego zatem dostëp takûe inne niû nasz
  92. programy, czyli mogâ do niego wysyîaê komunikaty i czekaê (czego
  93. nie powinny robiê), aû do portu wpîynie jakiô komunikat; czyniâc
  94. port publicznym, trzeba mieê naprawdë do tego powód, bo wtedy
  95. naleûy byê przygotowanym wîaôciwie na wszystko. No i -- jak juû
  96. sië domyôlasz -- port prywatny to taki, którego adres jest znany
  97. tylko nam.
  98.  
  99. Skoro zaô o tym wspomniaîem przed opisaniem tych dwóch procedur,
  100. îatwo jest sië domyôliê, ûe sâ one wîaônie z typami tych portów
  101. zwiâzane. Struktura portu publicznego absolutnie niczym sië nie
  102. róûni od struktury portu prywatnego -- w kaûdej chwili port
  103. prywatny moûesz wpisaê na listë portów publicznych -- do tego
  104. wîaônie sîuûy procedura _LVOAddPort(). _LVORemPort() uûywasz
  105. natomiast wtedy, gdy chcesz jakiô port z tej listy usunâê. Dziëki
  106. _LVOPutMsg() moûesz wysîaê wiadomoôê do jakiegoô portu, za pomocâ
  107. zaô _LVOGetMsg() odebraê jâ, gdy do naszego portu przybëdzie.
  108. _LVOWaitPort() zatrzymuje dziaîanie naszego programu do momentu,
  109. kiedy do portu podanego jako argument dla powyûszej procedury
  110. wpîynie wiadomoôê. _LVOFindPort() znajdzie nam adres portu o
  111. podanej nazwie z listy portów publicznych (oczywiôcie, jeôli taki
  112. istnieje). Dwie ostatnie procedury -- obecne w ROM-ie od
  113. systemów 2.0 w górë zakîadajâ (_LVOCreateMsgPort()) nowy port i
  114. kasujâ go (_LVODeleteMsgPort()) z pamiëci, czyli alokujâ
  115. (rezerwujâ) pamiëê potrzebnâ na strukturë naszego portu i
  116. wypeîniajâ pewnymi danymi, bez których port nie bëdzie dziaîaî
  117. oraz dealokujâ të pamiëê (zwalniajâ). Poniewaû -- jak juû
  118. wspomniaîem -- procedury te dostëpne sâ jedynie od systemu 2.0,
  119. na niûszych systemach musimy sië sami zatroszczyê o poprawne
  120. zbudowanie struktury portu. Jak taka struktura wyglâda? Ano tak:
  121.  
  122. <l>
  123.  
  124.     NT_MSGPORT    Equ    4
  125.  
  126.     MsgPort:    dc.l    0    ; mp_MsgNode....ln_Succ
  127.  
  128.         dc.l    0    ; ln_Pred
  129.  
  130.         dc.b    NT_MSGPORT    ; ln_Type
  131.  
  132.     dc.b    0    ; ln_Pri
  133.  
  134.     dc.l    PortName    ; ln_Name
  135.  
  136.     dc.b    0    ; mp_Flags
  137.  
  138.     dc.b    0    ; mp_SigBit
  139.  
  140.     dc.l    0    ; mp_SigTask/mp_SoftInt
  141.  
  142.     dc.l    0    ; mp_MsgList    lh_Head
  143.  
  144.     dc.l    0    ;     lh_Tail
  145.  
  146.     dc.l    0    ;     lh_TailPred
  147.  
  148.     dc.b    0    ;     lh_Type
  149.  
  150.     dc.b    0    ;     lh_pad
  151.  
  152.  
  153.     PortName:    dc.b    "Amsterdam",0
  154.  
  155. <txt>Jak widaê, nasz port skîada sië z trzech pomniejszych
  156. struktur: ze struktury Node, z pól charakterystycznych dla
  157. naszego portu i ze struktury List. Struktura Node (piëê
  158. pierwszych pól) ma swoje zasîuûone miejsce w systemie Amigi. Jest
  159. ona doîâczana do wielu innych struktur, co wskazuje na jej
  160. uniwersalnoôê. I rzeczywiôcie. Dwa pierwsze pola moûemy spokojnie
  161. wyzerowaê. Sâ one uûywane przez system, jeôli dopisaê nasz
  162. MsgPort do listy portów publicznych (w pierwszym bëdzie adres
  163. nastëpnego portu -- lub zero, jeôli nasz port jest ostatni na
  164. liôcie, w drugim poprzedniego lub zero, jeôli nasz port jest
  165. pierwszy na liôcie; nie powinno sië tych pól ani modyfikowaê, ani
  166. odczytywaê -- sâ one do uûytku przez system). Trzecie pole --
  167. ln_Type -- mówi nam o tym, do czego struktura Node jest
  168. doczepiona. Poniewaû jest to port, ustawiamy wartoôê tego pola na
  169. NT_MSGPORT (czyli 4). Nastëpny bajt -- ln_Pri -- to priorytet
  170. naszego portu. Jeôli nasz program (port) bëdzie czësto
  171. wyszukiwany z listy systemowej, warto ustawiê të wartoôê na
  172. wiëkszâ od zera -- ulokuje to nasz port bliûej poczâtku listy
  173. (lub moûe nawet na samym jej poczâtku), przez co zostanie
  174. szybciej znaleziony. Jeôli mamy ôwiadomoôê, ûe port bëdzie
  175. odszukany raz na tysiâc lat, moûna ustawiê priorytet na mniejszy
  176. od zera -- wtedy port zostanie dodany bliûej koïca listy.
  177. Najczëôciej jednak ustawia sië to pole na zero.
  178.  
  179. Ostatnie pole struktury Node to wskaúnik na nazwë naszego portu.
  180. Jest ona dowolna i musi byê zakoïczona zerem. Wszystkie te pola
  181. mogâ byê wyzerowane, jeôli nie bëdziemy dodawaê naszego portu do
  182. listy (uwaga: mogâ byê one wyzerowane nawet, jeôli dodamy MsgPort
  183. do listy, ale w wypadku, gdy ln_Name bëdzie równe zero, nie licz
  184. na to, ûe znajdziesz adres tego portu, uûywajâc
  185. _LVOFindPort()...). A co, jeôli port o nazwie, jakâ nadaliômy
  186. naszemu portowi, juû istnieje? Tu jest maîy problem. Procedura
  187. _LVOAddPort() nie zwraca nam ûadnej informacji o tym, czy port,
  188. który chcemy dodaê, nie nazywa sië przypadkiem tak samo, jak
  189. jeden z listy. Ona po prostu dodaje nam nasz port do listy i nie
  190. przewiduje ûadnych kîopotów. Moûe wiëc wystâpiê sytuacja, gdy na
  191. liôcie bëdzie kilka portów o takiej samej nazwie (uûywajâc
  192. _LVOFindPort() dostaniesz adres portu znajdujâcego sië najwyûej
  193. na liôcie o danej nazwie). Dlatego, aby uniknâê tej sytuacji,
  194. warto uûyê _LVOFindPort() przed dodaniem naszej struktury MsgPort
  195. do listy publicznej, aby przekonaê sië, czy port o takiej nazwie
  196. juû istnieje. Jeôli tak, to moûemy wyjôê z programu, wysîaê do
  197. portu jakiô komunikat (np. o tym, ûe uruchomiono drugi taki sam
  198. program) i/albo zmieniê nazwë naszego portu (i oczywiôcie jeszcze
  199. raz uûyê _LVOFindPort(), aû do skutku...).
  200.  
  201. Trzy kolejne pola -- mp_Flags, mp_SigBit i mp_SigTask (lub
  202. mp_SoftInt; wyjaônienie dalej) wystëpujâ tylko w strukturze
  203. MsgPort. Najpierw jednak opiszë mp_SigTask. W polu tym
  204. najczëôciej znajduje sië adres naszego tasku (zadania), czyli
  205. mówiâc proôciej adres struktury opisujâcej nasz program. Tak
  206. naprawdë to uruchomienie kaûdego programu w systemie îâczy sië ze
  207. stworzeniem przez system dodatkowej struktury -- wîaônie Task
  208. (lub czasem Process), w której zawarte sâ pewne informacje
  209. dotyczâce naszego programu i otoczenia, w jakim zostaî on
  210. uruchomiony, np. tzw. current dir, nazwa naszego programu etc.
  211. Poniewaû z pustego i "Salamon" nie naleje, zatem adres naszego
  212. tasku musimy sami znaleúê i w tym polu umieôciê. Uûywamy do tego
  213. procedury _LVOFindTask() (takûe z exec.library; zauwaû, ûe
  214. funkcja ta dziaîa identycznie jak _LVOFindPort(), tyle ûe
  215. wyszukuje taski, a nie porty), jako parametr zaô (wskaúnik na
  216. nazwë zadania) podajemy zero -- oznacza to, ûe mamy znaleúê adres
  217. struktury bieûâcego tasku, a nie jakiegoô tam z systemowej listy
  218. tasków. Po zwróceniu adresu w d0, kopiujemy go wîaônie do pola
  219. mp_SigTask.
  220.  
  221. Ale i wtedy nasz port nie bëdzie jeszcze gotowy do dziaîania (o
  222. tym póúniej). Po co tam adres naszego tasku? Otóû multitasking
  223. jest zrealizowany -- najproôciej mówiâc -- wîaônie dziëki
  224. istnieniu listy z taskami, które sâ co chwila "po kawaîku"
  225. wykonywane (tzn. struktura Task zawiera informacje o ostatnio
  226. wykonanym rozkazie programu, który opisuje, i to ten program, a
  227. nie task, jest wykonywany). Kiedy czekamy na komunikat, nasz
  228. program nie robi nic, po co wiëc marnowaê czas procesora na
  229. niepotrzebne pëtle? Istnieje wiëc druga lista -- lista tasków
  230. czekajâcych, gdzie znajdujâ sië taski przeniesione z pierwszej
  231. listy dziëki uûyciu procedury _LVOWaitPort(). Skoro wiëc
  232. przenosimy task do innej listy, musimy znaê jego adres, stâd
  233. zatem wynika potrzeba wpisania do struktury MsgPort adresu
  234. naszego tasku. Po drugie zaô, kiedy port otrzyma komunikat, w
  235. ogólnoôci nasz task przenoszony jest z powrotem na listë tasków
  236. gotowych do wykonania, czyli znowu potrzebny jest jego adres.
  237. Chyba wiëc jasne, ûe jeôli to pole bëdzie wyzerowane, to nie ma
  238. co liczyê na poprawne dziaîanie, a w zasadzie na jakiekolwiek
  239. dziaîanie funkcji _LVOWaitPort()?
  240.  
  241. Jeôli tak, to jedziemy dalej. Pole mp_SigTask nazwa sië teû
  242. mp_SoftInt. Dlaczego? Wynika to z tego, ûe w zaleûnoôci od
  243. ustawienia flag w polu mp_Flags, nasz program moûe sië róûnie
  244. zachowywaê. Jeôli wiëc ustawimy odpowiedniâ flagë, nasz port moûe
  245. po otrzymaniu komunikatu spowodowaê wywoîanie przez system
  246. przerwania (_LVOCause()), którego adres struktury znajduje sië
  247. wîaônie w polu mp_SoftInt. Dlatego pole to ma dwie nazwy.
  248.  
  249. To tyle w tym odcinku, za miesiâc zajmë sië polem mp_Flags.
  250.  
  251.