ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

mruby-uvで普通のfile descriptorが読み出し可能になるまで待つ

libuv経由で(uv_fs_open などで)作ったファイルへの参照(uv_fs_t)は基本的に非同期IOになるので、libuvのイベントループで取り扱うのに向いている。参照。

そうでないような同期的なIOのfile descriptor(fd)、たとえば普通にパイプで作ったやつや、 eventfd のようなものをlibuvのループで非同期的に待ちたい時には、 uv_poll_t が使えるそう。

mruby-uv では UV::Poll がその構造体と関数をラップしている。以下はパイプの片割れをポーリングして、もう一方には UV::Timer 経由で遅れて書き込むまで待つ例。

r, w = IO.pipe

poll = UV::Poll.new(r.fileno, UV.default_loop)
poll.start(UV::Poll::READABLE) do |e|
  # e = 1 が渡ってくる。これは UV::Poll::READABLE の値
  puts "Event!!: #{e}"
  puts "Message: #{r.read.inspect}"

  # 読み出し可能になったらこのブロックは無限ループする。なので自分で止める
  poll.stop
end

count = 0
timer = UV::Timer.new(UV.default_loop)
timer.start(1000, 1000) do
  print "."
  count += 1
  if count > 10
    puts
    w.print "<message>"
    w.close
    timer.stop
  end
end

puts "Waiting..."
UV.run()
puts "Exit loop"

f:id:udzura:20170113175432g:plain

利用したmgem:

  • mruby-io
  • mruby-uv