Last active
November 23, 2022 12:42
-
-
Save garybernhardt/2963229 to your computer and use it in GitHub Desktop.
A queue that you can pass to IO.select.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A queue that you can pass to IO.select. | |
# | |
# NOT THREAD SAFE: Only one thread should write; only one thread should read. | |
# | |
# Purpose: | |
# Allow easy integration of data-producing threads into event loops. The | |
# queue will be readable from select's perspective as long as there are | |
# objects in the queue. | |
# | |
# Implementation: | |
# The queue maintains a pipe. The pipe contains a number of bytes equal to | |
# the queue size. | |
# | |
# Example use: | |
# queue = SelectableQueue.new | |
# readable, _, _ = IO.select([queue, $stdin]) | |
# print "got #{queue.pop}" if readable.contain?(queue) | |
# | |
class SelectableQueue | |
def initialize | |
@queue = Queue.new | |
@read_io, @write_io = IO.pipe | |
end | |
def <<(o) | |
@queue << o | |
# It doesn't matter what we write into the pipe, as long as it's one byte. | |
@write_io << '.' | |
self | |
end | |
def pop(nonblock=false) | |
o = @queue.pop(nonblock) | |
@read_io.read(1) | |
o | |
end | |
def to_io | |
@read_io | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative "../selectable_queue" | |
describe SelectableQueue do | |
let(:q) { SelectableQueue.new } | |
it "queues objects" do | |
q << 1 << 2 | |
q.pop.should == 1 | |
q.pop.should == 2 | |
expect { q.pop(true) }.to raise_error(ThreadError) | |
end | |
it "is not selectable when empty" do | |
readable, _, _ = IO.select([q], nil, nil, 0) | |
readable.should == nil | |
end | |
it "is selectable when there are objects in it" do | |
q << 1 | |
readable, _, _ = IO.select([q], nil, nil, 0) | |
readable.should == [q] | |
end | |
it "is not selectable after being emptied" do | |
q << 1 | |
q.pop | |
readable, _, _ = IO.select([q], nil, nil, 0) | |
readable.should == nil | |
end | |
end |
I know this was written some time ago but the array variable readable does not have a method called .contain? did you mean .member? or .include?. I don't remember if there was a .contain? in the past. I was testing your example on Ruby 2.3.3 and it was throwing an exception on that call in a thread.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
👍 Thanks for sharing this