Урожай текущего волокна, пока FD имеет некоторые данные - PullRequest
0 голосов
/ 04 января 2019

В программе Crystal, которая использует библиотеку C через FFI, у меня есть код, который блокируется при чтении из файлового дескриптора. Как я могу получить волокно, пока в этом дескрипторе файла не будет данных?

например. текущий код выглядит примерно так:

f = File.open("/some/socket/or/pipe/like/object")
Iterator.of do
  data = Pointer(LibFoo::Data).malloc
  # yield_until_fd_has_data f.fd
  LibFoo.read f.fd, data
  data.value
end

Где LibFoo.read блокируется до тех пор, пока в объекте типа сокета / трубы не будет данных. Что я использую вместо yield_until_fd_has_data?

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Вероятно, вы можете использовать poll с нулевым тайм-аутом, чтобы получить состояние готовности файлового дескриптора. Вам нужно будет написать привязки C для этой функции самостоятельно, она не доступна в stdlib.

А потом это просто что-то вроде

while LibC.poll(fd_struct, 1, 0) == 0
   Fiber.yield
end
0 голосов
/ 05 января 2019

Один из способов, который я нашел до сих пор, - это создать подкласс IO::FileDescriptor и переопределить метод resume_read. Затем используйте Crystal::EventLoop.create_fd_read_event(my_subclass).add, что вызовет переопределенный метод resume_read, когда FD будет готов к чтению.

Однако это, кажется, несколько зависит от внутренних органов, поэтому может сломаться в будущем. Пока я использую это, но я бы хотел увидеть официальное решение.

...