在通过FFI使用C库的Crystal程序中,我有从文件描述符读取时阻塞的代码。在该文件描述符包含一些数据之前,我该如何生产光纤?
例如当前代码如下:
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
?
答案 0 :(得分:0)
到目前为止,我发现的一种方法是子类IO::FileDescriptor
并重写resume_read
方法。然后使用Crystal::EventLoop.create_fd_read_event(my_subclass).add
,当FD准备读取时,这将导致覆盖的resume_read
方法被调用。
但是,这似乎在某种程度上取决于内部结构,因此将来可能会中断。目前,我正在使用它,但是我很想看到一个官方的解决方案。
答案 1 :(得分:0)
您可以将poll
与零超时一起使用来获取文件描述符的就绪状态。您需要自己为此函数编写C绑定,但在stdlib中不可用。
然后就像
while LibC.poll(fd_struct, 1, 0) == 0
Fiber.yield
end