public
Last active

A queue that you can pass to IO.select. This is for use in a GUI application. I'm not turning into a Node programmer.

  • Download Gist
selectable_queue.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
# 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
selectable_queue_spec.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.