Slide 1

Slide 1 text

ͨͷ͍͠4PDLFUͷ͘͠Έ ԘҪඒ࡙ !TIJPJNN!DPF@!DPF 5PLZP8PNFOSCট଴ެԋ Socket Under a Microscope

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

QQTFMG ɹԘҪඒ࡙ ͓͍͠ ɹ஍Ҭ3VCZίϛϡχςΟ"TBLVTBSC ɹ3VCZίϛολʔ ɹલ਎Πϕϯτ5PLZP(JSMTSC.FFUVQWPMʹొஃͯ͠·ͨ͠ !TIJPJNN (JU)VC !DPF@ FY5XJUUFS !DPF #MVFTLZ 3BDLϛυϧ΢ΣΞೖ໳ͷͨΊͷ3BDLϛυϧ΢ΣΞ IUUQTTQFBLFSEFDLDPNDPF@SBDLNJEPSVVFBSVNFOGBMTFUBNFGBMTFSBDLNJEPSVVFB

Slide 4

Slide 4 text

5PLZP8PNFOSCλΠϜςʔϒϧ IUUQTUPLZPXPNFOSCDPOOQBTTDPNFWFOU

Slide 5

Slide 5 text

5PLZP8PNFOSCλΠϜςʔϒϧ ਪ͠ϝιουsource_locationͷ͘͠ΈΛ୳Δ - ͸͡ΊͯRubyͷίʔυΛಡΜͰΈͨ ਪ͠ϝιουTPVSDF@MPDBUJPOͷ͘͠ΈΛ୳Δ ͸͡Ίͯ3VCZͷίʔυΛಡΜͰΈͨ ͨͷ͍͠4PDLFUͷ͘͠Έ 4PDLFUT6OEFSB.JDSPTDPQF 3BJMTͷίʔυͰֶͿ ͱͷ࢓૊Έ ͘͠Έ͕ؾʹͳΔਓʑ find_by_* method_missing nobu09 OPCV ͓͍͠ NBJNV IUUQTUPLZPXPNFOSCDPOOQBTTDPNFWFOU

Slide 6

Slide 6 text

5PLZP8PNFOSCςʔϚ ʮ3VCZ͓ͬͯ΋͠Ζ͍ʂʯ ͱ͍͏͜ͱͰɺࣗ෼ʹͱͬͯͷ ʮ3VCZ͓ͬͯ΋͠Ζ͍ʂʯͷ͏ͪͻͱͭʹ͍ͭͯ ͓࿩͍ͨ͠͠ͱࢥ͍·͢

Slide 7

Slide 7 text

5PLZP8PNFOSCςʔϚ ʮ3VCZ͓ͬͯ΋͠Ζ͍ʂʯ ͱ͍͏͜ͱͰɺࣗ෼ʹͱͬͯͷ ʮ3VCZ͓ͬͯ΋͠Ζ͍ʂʯͷ͏ͪͻͱͭʹ͍ͭͯ ͓࿩͍ͨ͠͠ͱࢥ͍·͢ ➡︎ 4PDLFU

Slide 8

Slide 8 text

ඵͰΘ͔Διέοτ ྫ͑͹ʜ ΫϥΠΞϯτ͕αʔό΁ϦΫΤετΛૹΔ ➡︎ αʔό͕ϦΫΤετΛड͚औΓ8FCΞϓϦέʔγϣϯΛ࣮ߦ ➡︎ αʔό͕ͦͷ࣮ߦ݁ՌΛϨεϙϯεͱͯ͠ΫϥΠΞϯτʹૹΔ ϦΫΤετ Ϩεϙϯε 8FCΞϓϦέʔγϣϯ ΫϥΠΞϯτϗετ αʔόϗετ

Slide 9

Slide 9 text

ඵͰΘ͔Διέοτ ιέοτʜϗετʹͱͬͯͷ௨৴ͷग़ೖΓޱ Ϩεϙϯε ΫϥΠΞϯτϗετ αʔόϗετ ιέοτ ϗετ͸௨৴Λߦ͏ࡍʹιέοτΛ࡞੒͠ɺ͜ΕΛհͯ͠ ωοτϫʔΫͷ޲͜͏ଆʹσʔλΛૹ৴ͨ͠Γ ωοτϫʔΫͷ޲͜͏ଆ͔ΒσʔλΛड৴ͨ͠Γ͢Δ ϦΫΤετ 8FCΞϓϦέʔγϣϯ

Slide 10

Slide 10 text

ඵͰΘ͔Δ4PDLFU ιέοτʜϗετʹͱͬͯͷ௨৴ͷग़ೖΓޱ ϦΫΤετ Ϩεϙϯε ιέοτ 8FCΞϓϦέʔγϣϯ ΫϥΠΞϯτϗετ αʔόϗετ ιέοτ"1*ʜιέοτΛૢ࡞͢ΔͨΊͷ"1* TPDLFUϥΠϒϥϦʜ3VCZ͔Βιέοτ"1*Λѻ͏ͨΊͷϥΠϒϥϦ

Slide 11

Slide 11 text

3VCZͷTPDLFUϥΠϒϥϦΛ࢖͏ͱɺ ؆୯ʹΫϥΠΞϯτɾαʔόϓϩάϥϜ Λͭ͘Δ͜ͱ͕Ͱ͖·͢

Slide 12

Slide 12 text

αʔόϓϩάϥϜ αʔό

Slide 13

Slide 13 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό 4PDLFUUDQ@TFSWFS@MPPQϝιου TPDLFUϥΠϒϥϦΛSFRVJSF

Slide 14

Slide 14 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό ࣗ਎ͷϗετ໊MPDBMIPTU αʔόࣗ਎ͷϙʔτ൪߸

Slide 15

Slide 15 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό αʔόͱͯ͠ߦ͏ॲཧ

Slide 16

Slide 16 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτ 4PDLFUΦϒδΣΫτ ιέοτΛ3VCZͷΦϒδΣΫτͰϥοϓ͠ɺ ɹ3VCZ͔Βѻ͑ΔΑ͏ʹͨ͠΋ͷ

Slide 17

Slide 17 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτ ͜͜ͰϒϩοΫม਺ʹ౉ͬͯ͘Δͷ͸ɺ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ

Slide 18

Slide 18 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτΛಡΈࠐΈ ΫϥΠΞϯτ͔ΒͷϦΫΤετϝοηʔδΛऔಘ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ

Slide 19

Slide 19 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό 4PDLFUΦϒδΣΫτʹॻ͖ࠐΈ ΫϥΠΞϯτ΁ϨεϙϯεΛૹ৴ ͜͜Ͱ͸ϦΫΤετϝοηʔδΛ ͓͏Ήฦ͠ʹΫϥΠΞϯτʹૹ৴͍ͯ͠Δ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ

Slide 20

Slide 20 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό Ұ௨ΓΫϥΠΞϯτʹର͢Δૢ࡞͕ऴΘͬͨΒ ઀ଓࡁΈ4PDLFUΦϒδΣΫτͷೖग़ྗΛΫϩʔζ ϦΫΤετΛૹ৴ͨ͠ΫϥΠΞϯτͱ ઀ଓࡁΈͷঢ়ଶͷ4PDLFUΦϒδΣΫτ

Slide 21

Slide 21 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό ϦΫΤετΛड͚ͯϨεϙϯεΛฦ͢ɺͱ͍͏Ұ࿈ͷྲྀΕΛϧʔϓ

Slide 22

Slide 22 text

αʔόϓϩάϥϜ require "socket" Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end αʔό ΫϥΠΞϯτ͔ΒϦΫΤετΛड৴͠ɺ ͦΕΛͦͷ··ΫϥΠΞϯτʹϨεϙϯεͱͯ͠ ૹ৴͢Δ؆୯ͳ5$1ΤίʔαʔόϓϩάϥϜ a׬੒

Slide 23

Slide 23 text

ΫϥΠΞϯτϓϩάϥϜ ΫϥΠΞϯτ

Slide 24

Slide 24 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ TPDLFUϥΠϒϥϦΛSFRVJSF 4PDLFUUDQϝιου

Slide 25

Slide 25 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ Ѽઌϗετ໊MPDBMIPTU Ѽઌϙʔτ൪߸

Slide 26

Slide 26 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ ΫϥΠΞϯτͱͯ͠ߦ͏ॲཧ

Slide 27

Slide 27 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ

Slide 28

Slide 28 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ 4PDLFUΦϒδΣΫτʹॻ͖ࠐΈ αʔό΁ϦΫΤετϝοηʔδΛૹ৴ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ

Slide 29

Slide 29 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ 4PDLFUΦϒδΣΫτΛಡΈࠐΈ αʔό͔ΒϨεϙϯεϝοηʔδΛऔಘ ϨεϙϯεϝοηʔδΛඪ४ग़ྗ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ

Slide 30

Slide 30 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ ॲཧ͕ऴΘΔͱ4PDLFUΦϒδΣΫτ͸ࣗಈతʹΫϩʔζ Ѽઌͷαʔόͱ઀ଓࡁΈͷঢ়ଶͷ 4PDLFUΦϒδΣΫτ

Slide 31

Slide 31 text

ΫϥΠΞϯτϓϩάϥϜ require "socket" Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end ΫϥΠΞϯτ αʔόʹϦΫΤετ )J Λૹ৴͠ɺ αʔό͔Βड৴ͨ͠ϨεϙϯεΛͦͷ··ग़ྗ͢Δ ؆୯ͳ5$1ΫϥΠΞϯτϓϩάϥϜ a׬੒

Slide 32

Slide 32 text

σϞ

Slide 33

Slide 33 text

4PDLFUUDQ@TFSWFS@MPPQ4PDLFUUDQͷߏ଄ Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end αʔό ΫϥΠΞϯτ ΫϥΠΞϯτͱͷ઀ଓޙʹߦ͏࢓ࣄ αʔόͱͷ઀ଓޙʹߦ͏࢓ࣄ αʔόʵΫϥΠΞϯτؒͷ઀ଓཱ͕֬ͨ͠ޙʹߦ͏ॲཧΛ ֤ϝιουͷϒϩοΫ಺ʹهड़͍ͯ͠Δ

Slide 34

Slide 34 text

Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end αʔό ΫϥΠΞϯτ ωοτϫʔΫΛհ͓ͯ͠ޓ͍ʹ઀ଓཱ͕֬͢Δ·Ͱͷॲཧ͸ ͦΕͧΕͷϝιουࣗ਎͕ߦͳ͍ͬͯΔ 4PDLFUUDQ@TFSWFS@MPPQ4PDLFUUDQͷߏ଄ ΫϥΠΞϯτͱͷ઀ଓ αʔόͱͷ઀ଓ

Slide 35

Slide 35 text

Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end αʔό ΫϥΠΞϯτ ͦͷཪଆͰ3VCZ͸ͲͷΑ͏ʹιέοτΛѻ͍ɺ઀ଓ͍ͯ͠Δ 4PDLFUUDQ@TFSWFS@MPPQ4PDLFUUDQͷߏ଄ Ͳ͏΍ͬͯΫϥΠΞϯτͱ઀ଓ͍ͯ͠Δ Ͳ͏΍ͬͯαʔόͱ઀ଓ͍ͯ͠Δ

Slide 36

Slide 36 text

ɾ3VCZ .3* ɹIUUQTHJUIVCDPNSVCZSVCZUSFFSVCZ@@ ɾಈ࡞؀ڥ͸NBD04Λ૝ఆ ͨͷ͍͠4PDLFUͷ͘͠Έ Socket Under a Microscope

Slide 37

Slide 37 text

4PDLFUUDQ ΫϥΠΞϯτ ฤ Socket.tcp("localhost", 4567) do |sock| sock.write "Hi" message = sock.read puts message end

Slide 38

Slide 38 text

4PDLFUUDQ class Socket # ... def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) # ... end # ... end 4PDLFUUDQ͸4PDLFUΫϥεʹ Ϋϥεϝιουͱ࣮ͯ͠૷͞Ε͍ͯΔ FYUTPDLFUMJCTPDLFUSC

Slide 39

Slide 39 text

4PDLFUUDQ class Socket # ... def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end # ... end # ... end FYUTPDLFUMJCTPDLFUSC

Slide 40

Slide 40 text

4PDLFUUDQ class Socket # ... def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end # ... end # ... end FYUTPDLFUMJCTPDLFUSC ಛఆͷ৚݅Ͱ෼ذ ίʔυϦʔσΟϯάͷ༰қ͔͞Βɺ 
 ࠓճ͸ͪ͜ΒΛಡΈ·͢

Slide 41

Slide 41 text

4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil, :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end FYUTPDLFUMJCTPDLFUSC

Slide 42

Slide 42 text

4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil, :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end FYUTPDLFUMJCTPDLFUSC "EESJOGPGPSFBDI

Slide 43

Slide 43 text

"EESJOGPGPSFBDI FYUTPDLFUMJCTPDLFUSC class Addrinfo # ... def self.foreach(nodename, service, ..., &block) Addrinfo.getaddrinfo(nodename, service, ...).each(&block) end # ... end

Slide 44

Slide 44 text

class Addrinfo # ... def self.foreach(nodename, service, ..., &block) Addrinfo.getaddrinfo(nodename, service, ...).each(&block) end # ... end "EESJOGPGPSFBDI "EESJOGPHFUBEESJOGP FYUTPDLFUMJCTPDLFUSC

Slide 45

Slide 45 text

"EESJOGPHFUBEESJOGP "EESJOGPHFUBEESJOGP͸ ౉͞Εͨϗετ໊ͱϙʔτ൪߸Λ*1ΞυϨεʹղܾ͠ɺ ͦͷ݁ՌҰཡΛ"EESJOGPΦϒδΣΫτͷ഑ྻͰฦ͢ϝιου (ྫ) Addrinfo.getaddrinfo("localhost", 4567, nil, :STREAM) => [#, #] ϗετ͕*1W*1W྆ํʹରԠ͍ͯ͠Δ৔߹ɺฦΓ஋ʹ͸ ͦͷ྆ํͷΞυϨεΛද͢"EESJOGPΦϒδΣΫτؚ͕·ΕΔ ϗετ໊ ϙʔτ൪߸ ໊લղܾͷώϯτ ղܾͰ͖ͨ*1ΞυϨεҰཡ

Slide 46

Slide 46 text

"EESJOGPΦϒδΣΫτ "EESJOGPΦϒδΣΫτ*1ΞυϨε৘ใΛද͢ΦϒδΣΫτ (ྫ) addrinfo # => # addrinfo.ip_address # => "127.0.0.1" addrinfo.ipv4? # => true addrinfo.pfamily # => addrinfo.socktype # => "EESJOGPΦϒδΣΫτʹΞΫηε͢Δ͜ͱͰ ΞυϨεʹؔ͢Δ৘ใΛऔಘͨ͠Γૢ࡞͢Δ͜ͱ͕Ͱ͖Δ ΞυϨεϑΝϛϦ (IPv6 / IPv4) Λද͢਺஋ ௨৴ͷछྨ (ετϦʔϜ / σʔλάϥϜ) Λද͢਺஋

Slide 47

Slide 47 text

class Addrinfo # ... def self.foreach(nodename, service, ..., &block) Addrinfo.getaddrinfo(nodename, service, ...).each(&block) end # ... end "EESJOGPGPSFBDI ྫɿ*1Wͱ*1W྆ํʹରԠ͍ͯ͠ΔϗετͰ ɹɹϗετ໊ͱͯ͠MPDBMIPTUΛ౉ͨ͠৔߹ "EESJOGPHFUBEESJOGP͸ϗετ໊Λ໊લղܾ͠ɺ *1WΞυϨεͱ*1WΞυϨεΛͦΕͧΕද͢ "EESJOGPΦϒδΣΫτΛཁૉʹ࣋ͭ഑ྻΛฦ͢ => [#, #] "localhost" FYUTPDLFUMJCTPDLFUSC

Slide 48

Slide 48 text

class Addrinfo # ... def self.foreach(nodename, service, ..., &block) Addrinfo.getaddrinfo(nodename, service, ...).each(&block) end # ... end "EESJOGPGPSFBDI "EESJOGPGPSFBDI͸͜ͷ഑ྻʹରͯ͠FBDIΛݺͼग़͠ɺ ֤"EESJOGPΦϒδΣΫτ͝ͱʹϒϩοΫΛ࣮ߦ͢Δ "EESJOGPΦϒδΣΫτͷ഑ྻʹର͢Δ "SSBZFBDI FYUTPDLFUMJCTPDLFUSC

Slide 49

Slide 49 text

4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil, :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end ϒϩοΫม਺ʹ౉͞ΕΔ"EESJOGPΦϒδΣΫτΛ༻͍ͯ ϒϩοΫ಺ͷॲཧΛ࣮ߦ͢Δ "EESJOGPΦϒδΣΫτ FYUTPDLFUMJCTPDLFUSC ࠶ͼ "EESJOGPGPSFBDI͕࣮ߦ͢ΔϒϩοΫ

Slide 50

Slide 50 text

4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil, :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... end FYUTPDLFUMJCTPDLFUSC "EESJOGPDPOOFDU

Slide 51

Slide 51 text

"EESJOGPDPOOFDU class Addrinfo # ... def connect(...) connect_internal(nil, ...) end # ... end FYUTPDLFUMJCTPDLFUSC

Slide 52

Slide 52 text

"EESJOGPDPOOFDU class Addrinfo # ... def connect(...) connect_internal(nil, ...) end # ... end "EESJOGPDPOOFDU@JOUFUOBM FYUTPDLFUMJCTPDLFUSC

Slide 53

Slide 53 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC

Slide 54

Slide 54 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX

Slide 55

Slide 55 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ϗετ಺෦Ͱ৽͍͠ιέοτΛ࡞੒͠ɺ ɹͦΕΛ4PDLFUΦϒδΣΫτͱͯ͠ ɹѻ͑ΔΑ͏ʹͯ͠ฦ͢

Slide 56

Slide 56 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ➡︎ ͦͷ࣮ଶ͸$ݴޠͰ࣮૷ 3VCZͷ͞ΒͳΔ಺ଆΛ ͷ͍͍͖ͧͯ·͠ΐ͏ ϗετ಺෦Ͱ৽͍͠ιέοτΛ࡞੒͠ɺ ɹͦΕΛ4PDLFUΦϒδΣΫτͱͯ͠ ɹѻ͑ΔΑ͏ʹͯ͠ฦ͢

Slide 57

Slide 57 text

4PDLFUJOJUJBMJ[F void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); // ... } FYUTPDLFUTPDLFUD

Slide 58

Slide 58 text

4PDLFUJOJUJBMJ[F void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); // ... } 3VCZͷ$"1*Λ࢖ͬͯ 4PDLFUΫϥεͱ4PDLFUJOJUJBMJ[F͕ఆٛ͞Ε͍ͯΔ FYUTPDLFUTPDLFUD 4PDLFUΫϥεΛఆٛ 4PDLFUJOJUJBMJ[FΛఆٛ

Slide 59

Slide 59 text

4PDLFUJOJUJBMJ[F void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); // ... } FYUTPDLFUTPDLFUD 4PDLFUJOJUJBMJ[Fͷ಺෦࣮૷ 4PDLFUJOJUJBMJ[F͸ ࣮ମͱͯ͠͸TPDL@JOJUJBMJ[Fؔ਺ʹ࣮૷͞Ε͍ͯΔ

Slide 60

Slide 60 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } FYUTPDLFUTPDLFUD

Slide 61

Slide 61 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } ϝιουͷҾ਺ͷॲཧ FYUTPDLFUTPDLFUD

Slide 62

Slide 62 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@TPDLFUؔ਺ FYUTPDLFUTPDLFUD

Slide 63

Slide 63 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@TPDLFUؔ਺͸಺෦Ͱ STPDL@TPDLFUؔ਺ΛݺΜͰ͍Δ FYUTPDLFUTPDLFUD

Slide 64

Slide 64 text

STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) { // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } FYUTPDLFUJOJUD

Slide 65

Slide 65 text

STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) { // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } TPDLFU γεςϜίʔϧ STPDL@TPDLFUؔ਺಺Ͱ TPDLFUͱ͍͏γεςϜίʔϧΛݺΜͰ͍Δ aॏཁ FYUTPDLFUJOJUD

Slide 66

Slide 66 text

Χʔωϧͱ͸ 6OJYܥ04ʹ͓͍ͯ04ͷத֩ͱͳΔιϑτ΢ΣΞ ϋʔυ΢ΣΞࢿݯΛ؅ཧ͠ɺϓϩάϥϜͷಈ࡞؀ڥΛఏڙ͢Δ γεςϜίʔϧͱ͸ ͷલʹ ୅දతͳ6OJYܥ04NBD04ɺ'SFF#4%ɺ0QFO#4%ɺ-JOVYͳͲͳͲʜ Χʔωϧ 04ͷத֩෦෼

Slide 67

Slide 67 text

γεςϜίʔϧͱ͸ Χʔωϧ͕ఏڙ͢ΔػೳΛ ϓϩάϥϜ͔Βར༻͢ΔͨΊͷ࠷΋جຊతͳ"1* γεςϜίʔϧ ྫ ϑΝΠϧΛ։͘ɺಡΈॻ͖͢Δ ϓϩηεΛੜ੒͢Δ ωοτϫʔΫ௨৴Λߦ͏ Χʔωϧ 04ͷத֩෦෼ ϓϩάϥϜ

Slide 68

Slide 68 text

STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) { // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } ͜ͷϗετ಺ʹιέοτΛ࡞੒͢ΔΑ͏ Χʔωϧʹର໋ͯ͠ྩ͢Δ STPDL@TPDLFUؔ਺͸಺෦తʹTPDLFUΛݺͼग़͢͜ͱͰ ࣮ࡍʹϗετ಺ʹιέοτΛ࡞੒͍ͯ͠Δ FYUTPDLFUJOJUD TPDLFU γεςϜίʔϧ ϗετ ιέοτ

Slide 69

Slide 69 text

STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) { // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } TPDLFUγεςϜίʔϧ͸ɺ৽͘͠࡞੒ͨ͠ιέοτΛ ಛఆ͢ΔͨΊͷ൪߸ιέοτσΟεΫϦϓλΛฦ͢ ιέοτσΟεΫϦϓλΛऔಘ FYUTPDLFUJOJUD TPDLFU γεςϜίʔϧ

Slide 70

Slide 70 text

STPDL@TPDLFU static int rsock_socket0(int domain, int type, int proto) { // ... int result = socket(domain, type, proto); if (result == -1) return -1; rb_fd_fix_cloexec(result); #ifndef SOCK_NONBLOCK rsock_make_fd_nonblock(result); #endif return result; } औಘͨ͠ιέοτσΟεΫϦϓλΛฦͯ͠ऴྃ FYUTPDLFUJOJUD STPDL@TPDLFU͸৽͘͠࡞੒ͨ͠ιέοτͷ ιέοτσΟεΫϦϓλΛฦͯ͠ऴྃ͢Δ ιέοτσΟεΫϦϓλΛऔಘ TPDLFU γεςϜίʔϧ

Slide 71

Slide 71 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } FYUTPDLFUTPDLFUD ࠶ͼ STPDL@TPDLFUؔ਺ ৽͍͠ιέοτΛ࡞੒ͯ͠ ιέοτσΟεΫϦϓλΛฦ͢ ಺෦ͰSTPDL@TPDLFUؔ਺ΛݺΜͰ͍Δ

Slide 72

Slide 72 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@TPDLFUؔ਺ FYUTPDLFUTPDLFUD STPDL@TPDLFUؔ਺ͷฦΓ஋ ৽͘͠࡞੒ͨ͠ιέοτͷ ιέοτσΟεΫϦϓλ Λม਺GEʹ֨ೲ ࠶ͼ ৽͍͠ιέοτΛ࡞੒ͯ͠ ιέοτσΟεΫϦϓλΛฦ͢ ಺෦ͰSTPDL@TPDLFUؔ਺ΛݺͿ

Slide 73

Slide 73 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } STPDL@JOJU@TPDLؔ਺ FYUTPDLFUTPDLFUD STPDL@JOJU@TPDLؔ਺͸ม਺GEͷιέοτσΟεΫϦϓλΛ σʔλͱͯ͠อ࣋͢Δ4PDLFUΦϒδΣΫτΛ৽ͨʹ࡞੒͢Δ

Slide 74

Slide 74 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } ฦΓ஋ΛSFUVSO ࠷ޙʹɺTPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[F ͸ ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛฦͯ͠ऴྃ FYUTPDLFUTPDLFUD

Slide 75

Slide 75 text

TPDL@JOJUJBMJ[F 4PDLFUJOJUJBMJ[Fͷ࣮ମ static VALUE sock_initialize(int argc, VALUE *argv, VALUE sock) { VALUE domain, type, protocol; int fd; int d, t; rb_scan_args(argc, argv, "21", &domain, &type, &protocol); // ... fd = rsock_socket(d, t, NUM2INT(protocol)); if (fd < 0) rb_sys_fail("socket(2)"); return rsock_init_sock(sock, fd); } 4PDLFUOFXͷ಺෦࣮૷͸͜͜·Ͱ FYUTPDLFUTPDLFUD

Slide 76

Slide 76 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ࠶ͼ ϗετ಺෦Ͱ৽͍͠ιέοτΛ࡞੒͠ɺ ɹ͜ΕΛϥοϓ͢Δ4PDLFUΦϒδΣΫτΛฦ͢

Slide 77

Slide 77 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛม਺TPDLʹ֨ೲ ม਺TPDLʹରͯ͠4PDLFUDPOOFDU TFMGѼઌͷΞυϨε৘ใ "EESJOGPΦϒδΣΫτ

Slide 78

Slide 78 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC 4PDLFUDPOOFDU΋$Ͱ࣮૷͞Ε͍ͯΔ ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛม਺TPDLʹอଘ TFMGѼઌͷΞυϨε৘ใ "EESJOGPΦϒδΣΫτ ม਺TPDLʹରͯ͠4PDLFUDPOOFDU

Slide 79

Slide 79 text

4PDLFUDPOOFDU void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); // ... rb_define_method(rb_cSocket, "initialize", sock_initialize, -1); rb_define_method(rb_cSocket, "connect", sock_connect, 1); // ... } FYUTPDLFUTPDLFUD 4PDLFUDPOOFDUΛఆٛ 4PDLFUΫϥεΛఆٛ 4PDLFUDPOOFDUͷ಺෦࣮૷ 4PDLFUDPOOFDU͸ ࣮ମͱͯ͠͸TPDL@DPOOFDUؔ਺ʹ࣮૷͞Ε͍ͯΔ

Slide 80

Slide 80 text

static VALUE sock_connect(VALUE self, VALUE addr) { // ... int result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ FYUTPDLFUTPDLFUD

Slide 81

Slide 81 text

static VALUE sock_connect(VALUE self, VALUE addr) { // ... int result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ sock.connect(self) 4PDLFUDPOOFDUͷϨγʔό 4PDLFUΦϒδΣΫτ FYUTPDLFUTPDLFUD

Slide 82

Slide 82 text

static VALUE sock_connect(VALUE self, VALUE addr) { // ... int result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ sock.connect(self) ѼઌͷΞυϨε৘ใΛอ࣋͢Δ 4PDLFUDPOOFDUͷҾ਺ "EESJOGPΦϒδΣΫτ FYUTPDLFUTPDLFUD

Slide 83

Slide 83 text

static VALUE sock_connect(VALUE self, VALUE addr) { // ... int result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ STPDL@DPOOFDUؔ਺ FYUTPDLFUTPDLFUD Ϩγʔόͷ4PDLFUΦϒδΣΫτ Ҿ਺Ͱड͚औͬͨѼઌͷΞυϨε৘ใ sock.connect(self)

Slide 84

Slide 84 text

TPDL@DPOOFDU 4PDLFUDPOOFDUͷ࣮ମ static VALUE sock_connect(VALUE self, VALUE addr) { // ... int result = rsock_connect( self, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr), 0, RUBY_IO_TIMEOUT_DEFAULT ); // ... return INT2FIX(result); } STPDL@DPOOFDUؔ਺͸಺෦Ͱ DPOOFDU@CMPDLJOHؔ਺ΛݺΜͰ͍Δ FYUTPDLFUTPDLFUD

Slide 85

Slide 85 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } FYUTPDLFUJOJUD

Slide 86

Slide 86 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } FYUTPDLFUJOJUD Ҿ਺EBUB DPOOFDU@CMPDLJOHؔ਺͸Ҿ਺EBUBΛհͯ͠ STPDL@DPOOFDUؔ਺ʹ౉ͨ͠Ҿ਺ͷத਎Λड͚औΔ ɾϨγʔόͷ4PDLFUΦϒδΣΫτ͔Β औΓग़ͨ͠಺෦৘ใ ɾѼઌͷΞυϨε৘ใ ʜΛؚΉ

Slide 87

Slide 87 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } FYUTPDLFUJOJUD Ҿ਺EBUBͷத਎Λม਺BSHʹ֨ೲ

Slide 88

Slide 88 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } DPOOFDU@CMPDLJOHؔ਺಺Ͱ γεςϜίʔϧDPOOFDUΛݺͿ aॏཁ DPOOFDU γεςϜίʔϧ ࢦఆͷιέοτΛ࢖ͬͯѼઌͱͷ઀ଓΛ։࢝͢Δ FYUTPDLFUJOJUD ΫϥΠΞϯτ ઀ଓΛ։࢝ Ѽઌ ྫ

Slide 89

Slide 89 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } ม਺BSH͔ΒιέοτσΟεΫϦϓλΛऔΓग़͠ɺ DPOOFDUͷୈҰҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲͷιέοτΛ࢖͏͔ʯΛࢦఆ͍ͯ͠Δ FYUTPDLFUJOJUD ม਺BSH͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλ

Slide 90

Slide 90 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } ม਺BSH͔ΒऔΓग़ͨ͠઀ଓઌͷΞυϨε৘ใ ม਺BSH͔ΒѼઌͷΞυϨε৘ใΛऔΓग़͠ɺ DPOOFDUͷୈೋҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲ͜Ѽʹ઀ଓ͢Δ͔ʯΛࢦఆ͍ͯ͠Δ FYUTPDLFUJOJUD

Slide 91

Slide 91 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } ઀ଓʹ੒ޭ͢ΔͱDPOOFDU͸଴ػΛղআ͠ ౰֘ιέοτ͸Ѽઌϗετͱ઀ଓࡁΈͷঢ়ଶʹͳΔ FYUTPDLFUJOJUD ઀ଓࢼߦ։࢝ޙɺ઀ଓঢ়ଶ͕֬ఆ͢Δ·Ͱ଴ػ͢Δ ˞౰֘ιέοτ͕ϊϯϒϩοΩϯάϞʔυʹઃఆ͞Ε͍ͯͳ͍৔߹ ˞ ΫϥΠΞϯτ αʔό aa઀ଓཱ֬

Slide 92

Slide 92 text

DPOOFDU@CMPDLJOH static VALUE connect_blocking(void *data) { struct connect_arg *arg = data; return (VALUE)connect(arg->fd, arg->sockaddr, arg->len); } 4PDLFUDPOOFDUͷ಺෦࣮૷͸͜͜·Ͱ FYUTPDLFUJOJUD

Slide 93

Slide 93 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end FYUTPDLFUMJCTPDLFUSC ࠶ͼ 4PDLFUDPOOFDU ࢦఆͷιέοτΛ࢖ͬͯѼઌʹ઀ଓΛ։࢝͢Δ

Slide 94

Slide 94 text

"EESJOGPDPOOFDU@JOUFSOBM class Addrinfo # ... def connect_internal(...) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.connect(self) rescue Exception sock.close raise end # ... sock end # ... end "EESJOGPDPOOFDU@JOUFSOBM͸ɺѼઌϗετͱ ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛฦͯ͠ऴྃ αʔόͱ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛฦ͢ FYUTPDLFUMJCTPDLFUSC 4PDLFUDPOOFDU

Slide 95

Slide 95 text

4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil, :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... ret end FYUTPDLFUMJCTPDLFUSC ࠶ͼ "EESJOGPDPOOFDU 4PDLFUΦϒδΣΫτΛ࡞੒ˠ઀ଓ ಺෦Ͱ"EESJOGPDPOOFDU@JOUFSOBMΛݺͿ

Slide 96

Slide 96 text

4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil, :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... ret end "EESJOGPDPOOFDUͷฦΓ஋ͱͯ͠ ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛม਺SFUʹอଘ্ͨ͠ "EESJOGPGPSFBDIͷϧʔϓΛCSFBL ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ ม਺TPDLʹอଘ ม਺TPDLΛม਺SFUʹอଘͯ͠CSFBL FYUTPDLFUMJCTPDLFUSC

Slide 97

Slide 97 text

4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL def self.tcp_without_fast_fallback(host, port, ...) # ... Addrinfo.foreach(host, port, nil, :STREAM, ...) {|ai| # ... begin sock = ai.connect(...) rescue SystemCallError last_error = $! next end ret = sock break } # ... ret end ࠷ޙʹม਺SFU ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτ Λ ฦͯ͠4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL͸ऴྃ ฦΓ஋ FYUTPDLFUMJCTPDLFUSC

Slide 98

Slide 98 text

4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end FYUTPDLFUMJCTPDLFUSC ࠶ͼ 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛऔಘ

Slide 99

Slide 99 text

4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end FYUTPDLFUMJCTPDLFUSC ฦΓ஋ͷ4PDLFUΦϒδΣΫτΛม਺TPDLʹ֨ೲ 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDLͷฦΓ஋Ͱ͋Δ ઀ଓࡁΈ4PDLFUΦϒδΣΫτΛม਺TPDLʹอଘ 4PDLFUUDQ@XJUIPVU@GBTU@GBMMCBDL ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛऔಘ

Slide 100

Slide 100 text

4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯ 4PDLFUUDQͷϒϩοΫΛ࣮ߦ͢Δ FYUTPDLFUMJCTPDLFUSC Socket.tcp(...) do |sock| sock.write "Hi" message = sock.read puts message end

Slide 101

Slide 101 text

4PDLFUUDQ def self.tcp(host, port, ... fast_fallback: tcp_fast_fallback, &) sock = if fast_fallback && !(host && ip_address?(host)) tcp_with_fast_fallback(host, port, ...) else tcp_without_fast_fallback(host, port, ...) end if block_given? begin yield sock ensure sock.close end else sock end end ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯ 4PDLFUUDQͷϒϩοΫΛ࣮ߦ͢Δ Socket.tcp(...) do |sock| sock.write "Hi" message = sock.read puts message end aΰʔϧ FYUTPDLFUMJCTPDLFUSC

Slide 102

Slide 102 text

4PDLFUUDQͷ͘͠Έ ΫϥΠΞϯτ Socket.tcp Λ࣮ߦ

Slide 103

Slide 103 text

4PDLFUUDQͷ͘͠Έ ΫϥΠΞϯτ Socket.tcp 1. Addrinfo.getaddrinfo Λ࣮ߦ ϗετ໊Λ*1ΞυϨεʹղܾ͢Δ ΞυϨε৘ใΛ"EESJOGPΦϒδΣΫτͯ͠ѻ͑ΔΑ͏ʹ͢Δ

Slide 104

Slide 104 text

4PDLFUUDQͷ͘͠Έ ΫϥΠΞϯτ Socket.tcp 2. Socket.new (Socket#initialize) socket Λ࣮ߦ ϗετ಺ʹιέοτΛ࡞੒͢Δ ιέοτΛ4PLDFUΦϒδΣΫτͯ͠ѻ͑ΔΑ͏ʹ͢Δ ➡︎

Slide 105

Slide 105 text

4PDLFUUDQͷ͘͠Έ ΫϥΠΞϯτ Socket.tcp 3. Socket#connect connect Λ࣮ߦ ࡞੒ͨ͠ιέοτΛར༻͠ɺ ղܾͨ͠*1ΞυϨεѼʹ઀ଓ։࢝ˠ੒ޭͨ͠Β଴ػղআ αʔόͱ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛฦ͢ ➡︎

Slide 106

Slide 106 text

4PDLFUUDQͷ͘͠Έ ΫϥΠΞϯτ Socket.tcp 4. Λ࣮ߦ ͜ͷ4PDLFUΦϒδΣΫτʹ ϦΫΤετϝοηʔδΛॻ͖ࠐΜͩΓ ૹ৴ ϨεϙϯεϝοηʔδΛಡΈࠐΜͩΓ ड৴ ͢Δ ϒϩοΫΛ࣮ߦ aΰʔϧ

Slide 107

Slide 107 text

4PDLFUUDQ@TFSWFS@MPPQ αʔό ฤ Socket.tcp_server_loop("localhost", 4567) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end

Slide 108

Slide 108 text

4PDLFUUDQ@TFSWFS@MPPQ class Socket # ... def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end # ... end FYUTPDLFUMJCTPDLFUSC

Slide 109

Slide 109 text

class Socket # ... def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end # ... end 4PDLFUUDQ@TFSWFS@MPPQ 4PDLFUUDQ@TFSWFS@TPDLFUT ϗετ໊ ϙʔτ൪߸ FYUTPDLFUMJCTPDLFUSC 4PDLFUUDQ@TFSWFS@TPDLFUTΛݺͼग़͢ αʔόࣗ਎ͷ

Slide 110

Slide 110 text

4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets = tcp_server_sockets_port0(host) else last_error = nil sockets = [] begin # ... rescue Exception sockets.each(&:close) raise end # ... end end ϗετ໊ɾϙʔτ൪߸ FYUTPDLFUMJCTPDLFUSC

Slide 111

Slide 111 text

4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets = tcp_server_sockets_port0(host) else last_error = nil sockets = [] begin # ... rescue Exception sockets.each(&:close) raise end # ... end end ϙʔτ൪߸ʹΛ౉͍ͯ͠Δ৔߹ ϙʔτ൪߸ʹҎ֎Λ౉͍ͯ͠Δ৔߹ ίʔυϦʔσΟϯάͷ༰қ͔͞Βɺ ࠓճ͸ͪ͜ΒΛಡΈ·͢ ϗετ໊ɾϙʔτ൪߸ FYUTPDLFUMJCTPDLFUSC

Slide 112

Slide 112 text

4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ... Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end FYUTPDLFUMJCTPDLFUSC ˞if port == 0ͷelseઅͷத

Slide 113

Slide 113 text

4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ... Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end "EESJOGPGPSFBDI FYUTPDLFUMJCTPDLFUSC ˞if port == 0ͷelseઅͷத αʔόࣗ਎ͷϗετ໊ͷ໊લղܾΛߦ͏

Slide 114

Slide 114 text

4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ... Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end [#, #] FYUTPDLFUMJCTPDLFUSC "localhost" "EESJOGPΦϒδΣΫτ ˞if port == 0ͷelseઅͷத ˞ྫ ˞ྫ ղܾͨ͠*1ΞυϨεΛද͢"EESJOGPΦϒδΣΫτ͕ ϒϩοΫม਺BJʹ౉ͬͯ͘Δ

Slide 115

Slide 115 text

4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ... Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end "EESJOGPMJTUFO FYUTPDLFUMJCTPDLFUSC ˞if port == 0ͷelseઅͷத "EESJOGPΦϒδΣΫτ

Slide 116

Slide 116 text

"EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC

Slide 117

Slide 117 text

"EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC 4PDLFUOFX ৽͍͠4PDLFUΦϒδΣΫτΛ࡞੒͢Δ

Slide 118

Slide 118 text

"EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC ม਺TPDLʹରͯ͠4PDLFUCJOE TFMGαʔόࣗ਎ͷΞυϨε৘ใ "EESJOGPΦϒδΣΫτ ࡞੒ͨ͠4PDLFUΦϒδΣΫτʹରͯ͠ 4PDLFUCJOEϝιουΛݺͿ ࡞੒ͨ͠4PDLFUΦϒδΣΫτΛม਺TPDLʹ֨ೲ

Slide 119

Slide 119 text

4PDLFUCJOE void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); // ... rb_define_method(rb_cSocket, "bind", sock_bind, 1); // ... } 4PDLFUCJOE͸ ࣮ମͱͯ͠͸TPDL@CJOEؔ਺ʹ࣮૷͞Ε͍ͯΔ FYUTPDLFUTPDLFUD 4PDLFUCJOEΛఆٛ 4PDLFUΫϥεΛఆٛ 4PDLFUCJOEͷ಺෦࣮૷

Slide 120

Slide 120 text

TPDL@CJOE 4PDLFUCJOEͷ࣮ମ static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } FYUTPDLFUTPDLFUD

Slide 121

Slide 121 text

TPDL@CJOE 4PDLFUCJOEͷ࣮ମ static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } sock.bind(self) ୈҰҾ਺ʜ4PDLFUCJOEͷϨγʔό 4PDLFUΦϒδΣΫτ ୈೋҾ਺ʜ4PDLFUCJOEͷҾ਺ "EESJOGPΦϒδΣΫτ ࣗ਎ͷΞυϨε৘ใΛอ࣋͢Δ FYUTPDLFUTPDLFUD

Slide 122

Slide 122 text

static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ Ϩγʔόͷ4PDLFUΦϒδΣΫτ͔Β ಺෦৘ใΛऔಘͯ͠ม਺GQUSʹอଘ FYUTPDLFUTPDLFUD (FU0QFO'JMFϚΫϩ

Slide 123

Slide 123 text

static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ TPDL@CJOEؔ਺಺ͰγεςϜίʔϧCJOEΛݺΜͰ͍Δ aॏཁ FYUTPDLFUTPDLFUD ࢦఆͷιέοτʹಛఆͷΞυϨεΛඥ͚ͮΔ CJOE γεςϜίʔϧ

Slide 124

Slide 124 text

static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλΛ CJOEͷୈҰҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲͷιέοτΛ࢖͏͔ʯΛࢦఆ͍ͯ͠Δ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλ FYUTPDLFUTPDLFUD

Slide 125

Slide 125 text

static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ CJOEͷୈೋҾ਺ʹαʔόࣗ਎ͷΞυϨε৘ใΛ౉͢ɻ ͜ΕʹΑΓʮͲͷΞυϨεΛιέοτʹඥ͚ͮΔ͔ʯΛ ࢦఆ͍ͯ͠Δ ࣗ਎ͷΞυϨε৘ใ FYUTPDLFUTPDLFUD

Slide 126

Slide 126 text

static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ CJOEΛݺͼग़͢͜ͱʹΑΓɺ ʮͲͷιέοτ͕Ͳͷ*1ΞυϨεͰ ɹϦΫΤετΛ଴ػ͢Δ͔ʯΛࢦఆ͍ͯ͠Δ FYUTPDLFUTPDLFUD ϦΫΤετΛ଴ػ͢ΔΞυϨε *1ΞυϨεΛඥ෇͚ ྫ

Slide 127

Slide 127 text

static VALUE sock_bind(VALUE sock, VALUE addr) { VALUE rai; rb_io_t *fptr; SockAddrStringValueWithAddrinfo(addr, rai); GetOpenFile(sock, fptr); if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_SOCKLEN(addr)) < 0) { rsock_sys_fail_raddrinfo_or_sockaddr("bind(2)", addr, rai); } return INT2FIX(0); } TPDL@CJOE 4PDLFUCJOEͷ࣮ମ 4PDLFUCJOEͷ಺෦࣮૷͸͜͜·Ͱ FYUTPDLFUTPDLFUD *1ΞυϨεΛඥ෇͚

Slide 128

Slide 128 text

"EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC 4PDLFUCJOE ࢦఆͷιέοτͱࣗ਎ͷΞυϨεΛඥ͚ͮΔ ࠶ͼ

Slide 129

Slide 129 text

"EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC 4PDLFUMJTUFO

Slide 130

Slide 130 text

4PDLFUMJTUFO void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); // ... rb_define_method(rb_cSocket, "bind", sock_bind, 1); rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1); // ... } FYUTPDLFUTPDLFUD 4PDLFUΫϥεΛఆٛ 4PDLFUMJTUFO͸ ࣮ମͱͯ͠͸STPDL@TPDL@MJTUFOؔ਺ʹ࣮૷͞Ε͍ͯΔ 4PDLFUMJTUFOΛఆٛ 4PDLFUMJTUFOͷ಺෦࣮૷

Slide 131

Slide 131 text

STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); }

Slide 132

Slide 132 text

STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } 4PDLFUMJTUFOͷϨγʔό 4PDLFUΦϒδΣΫτ Ϩγʔόͷ4PDLFUΦϒδΣΫτ͔Β ಺෦৘ใΛऔಘͯ͠ม਺GQUSʹอଘ (FU0QFO'JMFϚΫϩ

Slide 133

Slide 133 text

VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ STPDL@TPDL@MJTUFOؔ਺಺Ͱ γεςϜίʔϧMJOTUFOΛݺΜͰ͍Δ aॏཁ MJTUFO γεςϜίʔϧ ࢦఆͷιέοτͰ઀ଓΛ଴ͪड͚Δ

Slide 134

Slide 134 text

VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλ ม਺GQUS͔ΒऔΓग़ͨ͠ιέοτσΟεΫϦϓλΛ MJTUFOͷୈҰҾ਺ʹ౉͢ɻ ͜ΕʹΑΓʮͲͷιέοτΛ࢖͏͔ʯΛࢦఆ͍ͯ͠Δ

Slide 135

Slide 135 text

VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ MJTUFOΛݺͼग़͢͜ͱʹΑΓɺ ࣮ࡍʹ͜ͷιέοτͰͷ઀ଓ଴ػ͕։࢝͢Δ ྫ ઀ଓ଴ͪ

Slide 136

Slide 136 text

VALUE rsock_sock_listen(VALUE sock, VALUE log) { rb_io_t *fptr; int backlog; backlog = NUM2INT(log); GetOpenFile(sock, fptr); if (listen(fptr->fd, backlog) < 0) rb_sys_fail("listen(2)"); return INT2FIX(0); } STPDL@TPDL@MJTUFO 4PDLFUMJTUFOͷ࣮ମ 4PDLFUMJTUFOͷ಺෦࣮૷͸͜͜·Ͱ ઀ଓ଴ͪ

Slide 137

Slide 137 text

"EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC ࠶ͼ 4PDLFUMJTUFO ࢦఆͷιέοτͰ઀ଓΛ଴ػ͢Δ

Slide 138

Slide 138 text

"EESJOGPMJTUFO class Addrinfo def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? # ... sock.bind(self) sock.listen(backlog) rescue Exception sock.close raise end # ... sock end end FYUTPDLFUMJCTPDLFUSC ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτ 4PDLFUΦϒδΣΫτΛฦͯ͠"EESJOGPMJTUFOΛऴྃ

Slide 139

Slide 139 text

4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ... Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end ࠶ͼ ˞if port == 0ͷelseઅͷத "EESJOGPMJTUFO ৽͘͠ιέοτΛ࡞੒ ɹˠࣗ෼ࣗ਎ͷΞυϨεΛඥ෇͚ ɹˠ઀ଓ଴ػΛ։࢝

Slide 140

Slide 140 text

4PDLFUUDQ@TFSWFS@TPDLFUT last_error = nil sockets = [] begin # ... Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end "EESJOGPMJTUFOͷฦΓ஋ͱͯ͠ ઀ଓ଴ػΛ։࢝ͨ͠4PDLFUΦϒδΣΫτΛ ഑ྻTPDLFUTʹ֨ೲ ม਺Tʹ֨ೲͨ͠4PDLFUΦϒδΣΫτΛ഑ྻTPDLFUTʹ֨ೲ ˞if port == 0ͷelseઅͷத "EESJOGPMJTUFO ฦΓ஋ͷ4PDLFUΦϒδΣΫτΛม਺Tʹ֨ೲ

Slide 141

Slide 141 text

last_error = nil sockets = [] begin # ... Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai| begin s = ai.listen rescue SystemCallError last_error = $! next end sockets << s # ... } # ... end [#, #] FYUTPDLFUMJCTPDLFUSC "localhost" ͜͜·Ͱͷॲཧ ιέοτͷ࡞੒ɺΞυϨεͷඥ෇͚ɺ ઀ଓ଴ػ։࢝ɺ഑ྻ΁ͷอଘ Λɺ໊લղܾͰऔಘͨ͠ ͢΂ͯͷ"EESJOGPΦϒδΣΫτʹରͯ͠܁Γฦ͢ ˞ྫ ˞ྫ "EESJOGPMJTUFO 4PDLFUUDQ@TFSWFS@TPDLFUT

Slide 142

Slide 142 text

4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end ઌ΄Ͳ·Ͱͷॲཧ 4PDLFUUDQ@TFSWFS@TPDLFUTϝιουͷଓ͖ "EESJOGPGPSFBDI͕ऴྃͯ͠ɺ if port == 0ͷelseઅΛൈ͚ͨޙ Ҿ͖ଓ͖ ഑ྻTPDLFUTʹ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτ͕อଘ͞Ε͍ͯΔ FYUTPDLFUMJCTPDLFUSC

Slide 143

Slide 143 text

4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end ͜ͷϝιουͷݺͼग़࣌͠ʹ౉͞Ε͍ͯͨ ϒϩοΫΛ࣮ߦ͢Δ def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end ઌ΄Ͳ·Ͱͷॲཧ FYUTPDLFUMJCTPDLFUSC ϒϩοΫ

Slide 144

Slide 144 text

4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end 4PDLFUBDDFQU@MPPQ ઌ΄Ͳ·Ͱͷॲཧ FYUTPDLFUMJCTPDLFUSC

Slide 145

Slide 145 text

4PDLFUUDQ@TFSWFS@TPDLFUT def self.tcp_server_sockets(host=nil, port, &b) if port == 0 sockets = tcp_server_sockets_port0(host) else end if block_given? begin yield sockets ensure sockets.each(&:close) end else sockets end end def self.tcp_server_loop(host=nil, port, &b) tcp_server_sockets(host, port) {|sockets| accept_loop(sockets, &b) } end ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ ઌ΄Ͳ·Ͱͷॲཧ FYUTPDLFUMJCTPDLFUSC

Slide 146

Slide 146 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end FYUTPDLFUMJCTPDLFUSC

Slide 147

Slide 147 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ 4PDLFUBDDFQU@MPPQ͸Ҿ਺ͱͯ͠ ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻΛड͚औΔ FYUTPDLFUMJCTPDLFUSC

Slide 148

Slide 148 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ϧʔϓॲཧ FYUTPDLFUMJCTPDLFUSC

Slide 149

Slide 149 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ϧʔϓॲཧ αʔό͸ΫϥΠΞϯτ͔ΒԿ౓΋ ϦΫΤετΛड͚ΔͨΊɺ Ұ࿈ͷॲཧΛϧʔϓͯ͠ߦ͍ͬͯΔ FYUTPDLFUMJCTPDLFUSC

Slide 150

Slide 150 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDU TPDLFUT઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ *0TFMFDUʹ઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻΛ ౉ͯ͠ݺͼग़͢ FYUTPDLFUMJCTPDLFUSC

Slide 151

Slide 151 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDU TPDLFUT઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ *0TFMFDU͸ Ҿ਺ʹ౉͍ͯ͠Δ4PDLFUΦϒδΣΫτͷ͍ͣΕ͔ʹ ϦΫΤετ͕ಧ͘·Ͱɺ͜͜ͰॲཧΛϒϩοΫ͢Δ FYUTPDLFUMJCTPDLFUSC

Slide 152

Slide 152 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDU TPDLFUT઀ଓ଴ػதͷ4PDLFUΦϒδΣΫτͷ഑ྻ ͍ͣΕ͔ͷ4PDLFUΦϒδΣΫτʹϦΫΤετ͕ಧ͘ͱɺ FYUTPDLFUMJCTPDLFUSC

Slide 153

Slide 153 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end *0TFMFDUͷฦΓ஋ SFBEBCMFϦΫΤετ͕ಧ͍ͨ4PDLFUΦϒδΣΫτͷ഑ྻ *0TFMFDU͸଴ػΛղআ͠ɺ ର৅ͷ4PDLFUΦϒδΣΫτΛཁૉʹ࣋ͭ ഑ྻSFBEBCMFΛฦ͢ FYUTPDLFUMJCTPDLFUSC

Slide 154

Slide 154 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) sockets.flatten!(1) if sockets.empty? raise ArgumentError, "no sockets" end loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end 4PDLFUBDDFQU@OPOCMPDL ϦΫΤετ͕ಧ͍ͨ4PDLFUΦϒδΣΫτʹରͯ͠ ॱʹ4PDLFUBDDFQU@OPOCMPDLϝιουΛݺͼग़͢ ϦΫΤετ͕ಧ͍ͨ4PDLFUΦϒδΣΫτ FYUTPDLFUMJCTPDLFUSC

Slide 155

Slide 155 text

4PDLFUBDDFQU@OPOCMPDL def accept_nonblock(exception: true) __accept_nonblock(exception) end FYUTPDLFUMJCTPDLFUSC

Slide 156

Slide 156 text

4PDLFUBDDFQU@OPOCMPDL def accept_nonblock(exception: true) __accept_nonblock(exception) end FYUTPDLFUMJCTPDLFUSC 4PDLFU@@BDDFQU@OPOCMPDL

Slide 157

Slide 157 text

4PDLFU@@BDDFQU@OPOCMPDL void Init_socket(void) { // ... rb_cSocket = rb_define_class("Socket", rb_cBasicSocket); // ... /* for ext/socket/lib/socket.rb use only: */ rb_define_private_method(rb_cSocket, "__accept_nonblock", sock_accept_nonblock, 1); // ... } FYUTPDLFUTPDLFUD 4PDLFU@@BDDFQU@OPOCMPDL͸$Ͱ࣮૷͞Ε͍ͯΔ TPDLFUSCϑΝΠϧ͔Βݺͼग़ͨ͢Ί͚ͩʹ࣮૷͞Ε͍ͯΔ 4PDLFUΫϥεΛఆٛ 4PDLFU@@BDDFQU@OPOCMPDLΛఆٛ 4PDLFU@@BDDFQU@OPOCMPDLͷ಺෦࣮૷

Slide 158

Slide 158 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD

Slide 159

Slide 159 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD 4PDLFUBDDFQU@OPOCMPDLͷϨγʔό 4PDLFUΦϒδΣΫτ

Slide 160

Slide 160 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD Ϩγʔόͷ4PDLFUΦϒδΣΫτͱ͸ผʹɺ ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ͢ΔͨΊͷ ม਺TPDLΛએݴ ͋ͱͰ࢖͏

Slide 161

Slide 161 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD 4PDLFUBDDFQU@OPOCMPDLͷϨγʔό 4PDLFUΦϒδΣΫτ Ϩγʔόͷ4PDLFUΦϒδΣΫτ͔Β ಺෦৘ใΛऔಘͯ͠ม਺GQUSʹอଘ (FU0QFO'JMFϚΫϩ

Slide 162

Slide 162 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ STPDL@T@BDDFQU@OPOCMPDLؔ਺ FYUTPDLFUTPDLFUD

Slide 163

Slide 163 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ Ϩγʔόͷ4PDLFUΦϒδΣΫτͷ಺෦৘ใ FYUTPDLFUTPDLFUD

Slide 164

Slide 164 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ STPDL@T@BDDFQU@OPOCMPDLؔ਺͸ ಺෦ͰDMPFYFD@BDDFQUؔ਺ΛݺΜͰ͍Δ FYUTPDLFUTPDLFUD

Slide 165

Slide 165 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } FYUTPDLFUJOJUD

Slide 166

Slide 166 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } FYUTPDLFUJOJUD Ϩγʔόͷ4PDLFUΦϒδΣΫτͷιέοτσΟεΫϦϓλ

Slide 167

Slide 167 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } DMPFYFD@BDDFQUؔ਺಺ͰγεςϜίʔϧ BDDFQUΛݺͿ BDDFQU γεςϜίʔϧ aॏཁ FYUTPDLFUJOJUD ΫϥΠΞϯτ͔ΒͷϦΫΤετΛ ࢦఆͷιέοτͰड͚ೖΕΔ ˞JGEFG)"7&@"$$&15͕GBMTFͷ৔߹

Slide 168

Slide 168 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } FYUTPDLFUJOJUD Ҿ਺ʹιέοτσΟεΫϦϓλΛ౉͠ɺ ʮͲͷιέοτͷϦΫΤετΛड͚෇͚Δͷ͔ʯΛࢦఆ Ϩγʔόͷ4PDLFUΦϒδΣΫτͷιέοτσΟεΫϦϓλ

Slide 169

Slide 169 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } BDDFQU͕ϦΫΤετΛड͚෇͚Δͱ FYUTPDLFUJOJUD ΫϥΠΞϯτ αʔό BDDFQU

Slide 170

Slide 170 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } ϦΫΤετΛ଴ͪड͚͍ͯΔιέοτ B ͱ͸ผʹ ΫϥΠΞϯτͱ઀ଓ͞Εͨ৽͍͠ιέοτ C ͕࡞੒͞ΕΔ FYUTPDLFUJOJUD ΫϥΠΞϯτ aa઀ଓཱ֬ αʔό C B

Slide 171

Slide 171 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } ΫϥΠΞϯτͱ઀ଓࡁΈͷιέοτͷ ιέοτσΟεΫϦϓλ BDDFQU͸৽͘͠࡞੒͞Εͨιέοτ C ͷ ιέοτσΟεΫϦϓλΛฦ͢ FYUTPDLFUJOJUD ΫϥΠΞϯτ αʔό C B aa઀ଓཱ֬

Slide 172

Slide 172 text

DMPFYFD@BDDFQU static int cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) { socklen_t len0 = 0; if (address_len) len0 = *address_len; #ifdef HAVE_ACCEPT4 // ... #else int result = accept(socket, address, ...); if (result == -1) return -1; rb_maygvl_fd_fix_cloexec(result); rsock_make_fd_nonblock(result); #endif if (address_len && len0 < *address_len) *address_len = len0; return result; } DMPFYFD@BDDFQUؔ਺͸৽͘͠࡞੒͞Εͨιέοτ C ͷ ιέοτσΟεΫϦϓλΛฦͯ͠ऴྃ FYUTPDLFUJOJUD ΫϥΠΞϯτ αʔό C B aa઀ଓཱ֬

Slide 173

Slide 173 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ FYUTPDLFUTPDLFUD ࠶ͼ STPDL@T@BDDFQU@OPOCMPDLؔ਺ ಺෦ͰDMPFYFD@BDDFQUؔ਺ΛݺͿ

Slide 174

Slide 174 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD STPDL@T@BDDFQU@OPOCMPDLؔ਺͸ ৽͘͠࡞੒ͨ͠ૉͷιέοτΛ 4PDLFUΦϒδΣΫτʹม׵ͯ͠ฦ͢ TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ

Slide 175

Slide 175 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ͢ΔͨΊͷม਺TPDLΛએݴ TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ STPDL@T@BDDFQU@OPOCMPDLؔ਺͸ ৽͘͠࡞੒ͨ͠ૉͷιέοτΛ 4PDLFUΦϒδΣΫτʹม׵ͯ͠ฦ͢

Slide 176

Slide 176 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ 4PDLFUΦϒδΣΫτͱ઀ଓઌΞυϨεΛද͢"EESJOGPΦϒδΣΫτΛ഑ྻʹͯ͠ฦ͢

Slide 177

Slide 177 text

static VALUE sock_accept_nonblock(VALUE sock, VALUE ex) { rb_io_t *fptr; VALUE sock2; union_sockaddr buf; struct sockaddr *addr = &buf.addr; socklen_t len = (socklen_t)sizeof buf; GetOpenFile(sock, fptr); sock2 = rsock_s_accept_nonblock(rb_cSocket, ex, fptr, addr, &len); if (SYMBOL_P(sock2)) return sock2; /* :wait_readable */ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, &buf.addr, len)); } FYUTPDLFUTPDLFUD TPDL@BDDFQU@OPOCMPDL 4PDLFU@@BDDFQU@OPOCMPDLͷ࣮ମ 4PDLFU@@BDDFQU@OPOCMPDLͷ಺෦࣮૷͸͜͜·Ͱ

Slide 178

Slide 178 text

4PDLFUBDDFQU@MPPQ ࠶ͼ def self.accept_loop(*sockets) # ... loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end 4PDLFUBDDFQU@OPOCMPDL ઀ଓΛड͚෇͚Δ

Slide 179

Slide 179 text

def self.accept_loop(*sockets) # ... loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end 4PDLFUBDDFQU@MPPQ 4PDLFUBDDFQU@OPOCMPDLͷฦΓ஋͔Β ม਺TPDLʹΫϥΠΞϯτͱ઀ଓࡁΈͷ ৽͍͠4PDLFUΦϒδΣΫτΛ֨ೲ 4PDLFUBDDFQU@OPOCMPDL ઀ଓΛड͚෇͚Δ

Slide 180

Slide 180 text

def self.accept_loop(*sockets) # ... loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end Socket.tcp_server_loop(...) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end 4PDLFUBDDFQU@MPPQ ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯϒϩοΫΛ࣮ߦ

Slide 181

Slide 181 text

4PDLFUBDDFQU@MPPQ def self.accept_loop(*sockets) # ... loop { readable, _, _ = IO.select(sockets) readable.each {|r| sock, addr = r.accept_nonblock(exception: false) next if sock == :wait_readable yield sock, addr } } end ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛ࢖ͬͯϒϩοΫΛ࣮ߦ aΰʔϧ Socket.tcp_server_loop(...) do |sock| message = sock.readpartial 100 sock.write message ensure sock.close end

Slide 182

Slide 182 text

4PDLFUUDQ@TFSWFS@MPPQͷ͘͠Έ αʔό Socket.tcp_server_loop Λ࣮ߦ

Slide 183

Slide 183 text

4PDLFUUDQ@TFSWFS@MPPQͷ͘͠Έ αʔό Socket.tcp_server_loop 1. Addrinfo.getaddrinfo Λ࣮ߦ ϗετ໊Λ*1ΞυϨεʹղܾ͢Δ ΞυϨε৘ใΛ"EESJOGPΦϒδΣΫτͯ͠ѻ͑ΔΑ͏ʹ͢Δ

Slide 184

Slide 184 text

4PDLFUUDQ@TFSWFS@MPPQͷ͘͠Έ αʔό Socket.tcp_server_loop 2. Socket.new (Socket#initialize) socket Λ࣮ߦ ϗετ಺ʹιέοτΛ࡞੒͢Δ ιέοτΛ4PLDFUΦϒδΣΫτͯ͠ѻ͑ΔΑ͏ʹ͢Δ ➡︎

Slide 185

Slide 185 text

4PDLFUUDQ@TFSWFS@MPPQͷ͘͠Έ αʔό Socket.tcp_server_loop 3. Socket#bind bind Λ࣮ߦ ࡞੒ͨ͠ιέοτͱղܾͨࣗ͠਎ͷΞυϨεΛඥ͚ͮΔ ➡︎

Slide 186

Slide 186 text

4PDLFUUDQ@TFSWFS@MPPQͷ͘͠Έ αʔό Socket.tcp_server_loop 4. Socket#listen listen Λ࣮ߦ ΞυϨεͱඥ͚ͮͨιέοτͰ઀ଓΛ଴ػ͢Δ ➡︎

Slide 187

Slide 187 text

4PDLFUUDQ@TFSWFS@MPPQͷ͘͠Έ αʔό Socket.tcp_server_loop 5. Socket#accept_nonblock accept Λ࣮ߦ ιέοτʹಧ͍ͨϦΫΤετΛड͚෇͚Δ ΫϥΠΞϯτͱ઀ଓࡁΈͷ4PDLFUΦϒδΣΫτΛฦ͢ ➡︎

Slide 188

Slide 188 text

αʔό Socket.tcp_server_loop 6. Λ࣮ߦ ϒϩοΫΛ࣮ߦ 4PDLFUUDQ@TFSWFS@MPPQͷ͘͠Έ aΰʔϧ ͜ͷ4PDLFUΦϒδΣΫτ͔Β ϦΫΤετϝοηʔδΛಡΈࠐΜͩΓ ड৴ ϨεϙϯεϝοηʔδΛॻ͖ࠐΜͩΓ ૹ৴ ͢Δ

Slide 189

Slide 189 text

·ͱΊ ɹ

Slide 190

Slide 190 text

·ͱΊ ͨͩͷײ૝ ɹ ιέοτ͓ͬͯ΋͠Ζ͍

Slide 191

Slide 191 text

ιέοτ͓ͬͯ΋͠Ζ͍ ιέοτϓϩάϥϛϯά ιέοτΛ࢖༻ͯ͠ωοτϫʔΫ্Ͱσʔλͷૹड৴Λ͢Δ͜ͱ

Slide 192

Slide 192 text

ιέοτ͓ͬͯ΋͠Ζ͍ ΫϥΠΞϯτͱαʔόɺͦΕͧΕ͕Ұ࿈ͷखଓ͖ʹԊͬͯ ιέοτ"1*Λૢ࡞͢Δ͜ͱʹΑͬͯɺ ΫϥΠΞϯτ αʔό ιέοτ ɾ ɾ ɾ ɾ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ ɾ ɾ γεςϜίʔϧ γεςϜίʔϧ socket connect socket bind listen accept ˞5$1ͷ৔߹

Slide 193

Slide 193 text

ιέοτ͓ͬͯ΋͠Ζ͍ ιέοτΛ௨ͯ͡ɺωοτϫʔΫͷ྆୺ʹ͍Δϗετಉ࢜Ͱ ίϛϡχέʔγϣϯΛऔΔ͜ͱ͕Ͱ͖Δ ΫϥΠΞϯτ αʔό Ϩεϙϯε ϦΫΤετ ɾ ɾ ɾ ɾ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ ɾ ɾ γεςϜίʔϧ γεςϜίʔϧ socket connect socket bind listen accept ˞5$1ͷ৔߹

Slide 194

Slide 194 text

ιέοτ͓ͬͯ΋͠Ζ͍ ͜ͷͱ͖ιέοτ͸ Θͨͨͪ͠ϓϩάϥϚʔʹͱͬͯ ωοτϫʔΫͷੈքΛ։͍ͯ͘ΕΔɺ ͦͯࣗ͠෼ͨͪͰϓϩάϥϛϯάͰ͖Δ Ұ൪਎ۙͳଘࡏ

Slide 195

Slide 195 text

΋͏ͻͱͭ ɹ

Slide 196

Slide 196 text

΋͏ͻͱͭ ɹ 3VCZ͓ͬͯ΋͠Ζ͍

Slide 197

Slide 197 text

4PDLFUUDQ4PDLFUUDQ@TFSWFS@MPPQͷେ෦෼͸3VCZ࣮૷ 3VCZ͓ͬͯ΋͠Ζ͍ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind Socket#listen Socket.accept_loop Socket#accept_nonblock Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new Socket#cennect ͷίʔϧελοΫ ͷίʔϧελοΫ

Slide 198

Slide 198 text

4PDLFUUDQ4PDLFUUDQ@TFSWFS@MPPQͷେ෦෼͸3VCZ࣮૷ ͜ΕΒͷ࣮૷ࣗମ͕3VCZΛ࢖ͬͨιέοτϓϩάϥϛϯά 3VCZ͓ͬͯ΋͠Ζ͍ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind Socket#listen Socket.accept_loop Socket#accept_nonblock Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new Socket#cennect ͷίʔϧελοΫ ͷίʔϧελοΫ

Slide 199

Slide 199 text

͜ͷͱ͖ιέοτΛ௚઀ૢ࡞͢Δ෦෼͸ɺ࣮ࡍ͸ 3VCZͷ಺෦Ͱ͸$Ͱ࣮૷͞Ε͍ͯΔ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind Socket#listen Socket.accept_loop Socket#accept_nonblock Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new Socket#cennect 3VCZ͓ͬͯ΋͠Ζ͍ ͷίʔϧελοΫ $࣮૷ $࣮૷ $࣮૷ $࣮૷ $࣮૷ $࣮૷ ͷίʔϧελοΫ

Slide 200

Slide 200 text

ͦΕΒ͸3VCZͷίʔυͷதͰ͸ 4PDLFUΦϒδΣΫτ΁ͷϝιουݺͼग़͠ͱͯ͠දݱ͞ΕΔ 3VCZ͓ͬͯ΋͠Ζ͍ Socket.tcp Socket.tcp_without_fast_fallback Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo.connect Addrinfo.connect_internal Socket.new Socket#cennect ͷίʔϧελοΫ $࣮૷ $࣮૷ Socket.tcp_server_loop Socket.tcp_server_sockets Addrinfo.foreach Addrinfo.getaddrinfo Addrinfo#listen Socket.new Socket#bind Socket#listen Socket.accept_loop Socket#accept_nonblock $࣮૷ $࣮૷ $࣮૷ $࣮૷ ͷίʔϧελοΫ

Slide 201

Slide 201 text

೉͍͜͠ͱ͸͢΂ͯ3VCZࣗ਎ͷதʹӅ͞Ε͍ͯΔ Θͨͨͪ͠͸ιέοτΛ ;ͭ͏ͷ3VCZΦϒδΣΫτͱͯ͠ѻ͏͜ͱ͕Ͱ͖Δ 3VCZ͓ͬͯ΋͠Ζ͍ Socket.new socket Socket#connect connect Socket#bind bind Socket#listen listen Socket#accept_nonblock accept ɾ ɾ ɾ ɾ ɾ ➡︎ ➡︎ ➡︎ ➡︎ ➡︎ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ γεςϜίʔϧ

Slide 202

Slide 202 text

3VCZ͓ͬͯ΋͠Ζ͍ ͜Εͬͯཁ͢Δʹ;ͭ͏ͷ3VCZϓϩάϥϛϯά

Slide 203

Slide 203 text

͜Εͬͯཁ͢Δʹ;ͭ͏ͷ3VCZϓϩάϥϛϯά 3VCZ͓ͬͯ΋͠Ζ͍ IUUQTUBOPTIJJSVCZHJUIVCJP ͦͯ͠3VCZϓϩάϥϛϯά͸ͨͷ͍͠

Slide 204

Slide 204 text

3VCZΛ࢖ͬͯ3VCZͷΑ͏ʹ ιέοτΛѻ͑͹ ιέοτϓϩάϥϛϯά͸ 3VCZϓϩάϥϛϯάͱಉ͡Α͏ʹ ͨͷ͍͠

Slide 205

Slide 205 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ ࢀߟਤॻ ɾ83JDIBSE4UFWFOT ࣰాཅҰ ຋༁ ɹʮ6/*9ωοτϫʔΫϓϩάϥϛϯά7PMୈ൛ ɹωοτϫʔΫ"1*ιέοτͱ95*ʯ ͨͷ͍͠4PDLFUͷ͘͠Έ Socket Under a Microscope