| Class | Irc::MessageQueue |
| In: |
lib/rbot/ircsocket.rb
|
| Parent: | Object |
# File lib/rbot/ircsocket.rb, line 153
153: def initialize
154: # a MessageQueue is an array of QueueRings
155: # rings have decreasing priority, so messages in ring 0
156: # are more important than messages in ring 1, and so on
157: @rings = Array.new(3) { |i|
158: if i > 0
159: QueueRing.new
160: else
161: # ring 0 is special in that if it's not empty, it will
162: # be popped. IOW, ring 0 can starve the other rings
163: # ring 0 is strictly FIFO and is therefore implemented
164: # as an array
165: Array.new
166: end
167: }
168: # the other rings are satisfied round-robin
169: @last_ring = 0
170: self.extend(MonitorMixin)
171: @non_empty = self.new_cond
172: end
# File lib/rbot/ircsocket.rb, line 174
174: def clear
175: self.synchronize do
176: @rings.each { |r| r.clear }
177: @last_ring = 0
178: end
179: end
# File lib/rbot/ircsocket.rb, line 181
181: def push(mess, chan=nil, cring=0)
182: ring = cring
183: self.synchronize do
184: if ring == 0
185: warning "message #{mess} at ring 0 has channel #{chan}: channel will be ignored" if !chan.nil?
186: @rings[0] << mess
187: else
188: error "message #{mess} at ring #{ring} must have a channel" if chan.nil?
189: @rings[ring].push mess, chan
190: end
191: @non_empty.signal
192: end
193: end
# File lib/rbot/ircsocket.rb, line 195
195: def shift(tmout = nil)
196: self.synchronize do
197: @non_empty.wait(tmout) if self.empty?
198: return unsafe_shift
199: end
200: end
# File lib/rbot/ircsocket.rb, line 208
208: def length
209: @rings.inject(0) { |s, r| s + r.size }
210: end
# File lib/rbot/ircsocket.rb, line 213
213: def unsafe_shift
214: if !@rings[0].empty?
215: return @rings[0].shift
216: end
217: (@rings.size - 1).times do
218: @last_ring = (@last_ring % (@rings.size - 1)) + 1
219: return @rings[@last_ring].shift unless @rings[@last_ring].empty?
220: end
221: warning "trying to access an empty message queue"
222: return nil
223: end