lib/zmachine/channel.rb in zmachine-0.2.1 vs lib/zmachine/channel.rb in zmachine-0.3.0
- old
+ new
@@ -2,15 +2,16 @@
module ZMachine
class Channel
attr_accessor :socket
+ attr_accessor :raw
def initialize
@inbound_buffer = ByteBuffer.allocate(1024 * 1024)
@outbound_queue = []
- @close_scheduled = false
+ @raw = false
end
# methods that need to be implemented in sub classes:
#
# selectable_fd
@@ -29,17 +30,49 @@
def can_send?
!@outbound_queue.empty?
end
- def close(after_writing = false)
- ZMachine.logger.debug("zmachine:channel:#{__method__}", channel: self, after_writing: after_writing) if ZMachine.debug
+ def send_data(data)
+ ZMachine.logger.debug("zmachine:channel:#{__method__}", channel: self) if ZMachine.debug
+ raise RuntimeError.new("send_data called after close") if @closed_callback
+ return unless data
+ buffer = ByteBuffer.wrap(data)
+ if buffer.has_remaining
+ @outbound_queue << buffer
+ end
+ end
+
+ def write_outbound_data
+ ZMachine.logger.debug("zmachine:channel:#{__method__}", channel: self, can_send: can_send?) if ZMachine.debug
+ while can_send?
+ buffer = @outbound_queue.first
+ @socket.write(buffer) if buffer.has_remaining
+ # Did we consume the whole outbound buffer? If yes,
+ # pop it off and keep looping. If no, the outbound network
+ # buffers are full, so break out of here.
+ break if buffer.has_remaining
+ @outbound_queue.shift
+ end
+ maybe_close_with_callback
+ end
+
+ def close(after_writing = false, &block)
+ return true if closed?
+ ZMachine.logger.debug("zmachine:channel:#{__method__}", channel: self, after_writing: after_writing, caller: caller[0].inspect) if ZMachine.debug
@close_scheduled = true
+ @closed_callback = block if block
@outbound_queue.clear unless after_writing
+ maybe_close_with_callback
end
- def close_after_writing
- close(true)
+ def maybe_close_with_callback
+ ZMachine.logger.debug("zmachine:channel:#{__method__}", channel: self, can_send: can_send?) if ZMachine.debug
+ return false if can_send?
+ return true unless @close_scheduled
+ close!
+ @closed_callback.call if @closed_callback
+ return true
end
end
end