Skip to content
Browse files

read and recv should behave differently

read should wait until it receives as much data as requested or it reaches EOF, rather than return a short read.

When EOF is reached, if some data has already been read, return a partial result.  Otherwise, return nil.
  • Loading branch information...
1 parent f07b2a1 commit 791a76f0fd70c1ab13c3697861b8c1025a76d0d5 @eliaslevy committed Nov 1, 2011
Showing with 49 additions and 3 deletions.
  1. +16 −3 lib/em-synchrony/tcpsocket.rb
  2. +33 −0 spec/tcpsocket_spec.rb
View
19 lib/em-synchrony/tcpsocket.rb
@@ -41,11 +41,23 @@ def send(msg, flags = 0)
end
alias_method :write, :send
- def read(num_bytes = 16*1024, dest = nil)
+ def recv(num_bytes = 16*1024, dest = nil)
read_data(num_bytes, dest) or sync(:in) or raise(IOError)
end
- alias_method :read_nonblock, :read
- alias_method :recv, :read
+ alias_method :read_nonblock, :recv
+
+ def read(num_bytes = 16*1024, dest = nil)
+ data = read_data(num_bytes) || ''
+ while not @closed and data.size != num_bytes
+ @read_bytes = num_bytes - data.size
+ d = sync(:in)
+ @closed = true if d.nil?
+ data += d || ''
+ end
+ return nil if @closed and data == ''
+ data
+ end
+
def close
close_connection true
@@ -60,6 +72,7 @@ def connection_completed
def unbind
@in_req.fail nil if @in_req
@out_req.fail nil if @out_req
+ @closed = true
end
def receive_data(data)
View
33 spec/tcpsocket_spec.rb
@@ -17,4 +17,37 @@
EM.stop
end
end
+
+ describe '#read' do
+ it 'waits until EOF' do
+ module EOFTest
+ def post_init
+ self.send_data "123"
+ EventMachine::add_timer(0.5) { self.close_connection_after_writing }
+ end
+ end
+ EventMachine.synchrony do
+ EventMachine::start_server 'localhost', 12345, EOFTest
+ @socket = EventMachine::Synchrony::TCPSocket.new 'localhost', 12345
+ @socket.read(6).should == '123'
+ EventMachine::Synchrony::sleep(1)
+ @socket.read(6).should be_nil
+ EM.stop
+ end
+ end
+ it 'waits until there is enough data' do
+ module EOFTest
+ def post_init
+ send_data "123"
+ EventMachine::add_timer(0.5) { self.send_data "4567890" }
+ end
+ end
+ EventMachine.synchrony do
+ EventMachine::start_server 'localhost', 12345, EOFTest
+ @socket = EventMachine::Synchrony::TCPSocket.new 'localhost', 12345
+ @socket.read(6).should == '123456'
+ EM.stop
+ end
+ end
+ end
end

0 comments on commit 791a76f

Please sign in to comment.
Something went wrong with that request. Please try again.