# File lib/rbot/ircsocket.rb, line 153 def initialize # a MessageQueue is an array of QueueRings # rings have decreasing priority, so messages in ring 0 # are more important than messages in ring 1, and so on @rings = Array.new(3) { |i| if i > 0 QueueRing.new else # ring 0 is special in that if it's not empty, it will # be popped. IOW, ring 0 can starve the other rings # ring 0 is strictly FIFO and is therefore implemented # as an array Array.new end } # the other rings are satisfied round-robin @last_ring = 0 self.extend(MonitorMixin) @non_empty = self.new_cond end
# File lib/rbot/ircsocket.rb, line 174 def clear self.synchronize do @rings.each { |r| r.clear } @last_ring = 0 end end
# File lib/rbot/ircsocket.rb, line 181 def push(mess, chan=nil, cring=0) ring = cring self.synchronize do if ring == 0 warning "message #{mess} at ring 0 has channel #{chan}: channel will be ignored" if !chan.nil? @rings[0] << mess else error "message #{mess} at ring #{ring} must have a channel" if chan.nil? @rings[ring].push mess, chan end @non_empty.signal end end
# File lib/rbot/ircsocket.rb, line 195 def shift(tmout = nil) self.synchronize do @non_empty.wait(tmout) if self.empty? return unsafe_shift end end
# File lib/rbot/ircsocket.rb, line 204 def empty? !@rings.find { |r| !r.empty? } end
# File lib/rbot/ircsocket.rb, line 208 def length @rings.inject(0) { |s, r| s + r.size } end
# File lib/rbot/ircsocket.rb, line 213 def unsafe_shift if !@rings[0].empty? return @rings[0].shift end (@rings.size - 1).times do @last_ring = (@last_ring % (@rings.size - 1)) + 1 return @rings[@last_ring].shift unless @rings[@last_ring].empty? end warning "trying to access an empty message queue" return nil end