Skip to content

Commit

Permalink
read and recv should behave differently
Browse files Browse the repository at this point in the history
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
eliaslevy committed Nov 8, 2011
1 parent f07b2a1 commit 791a76f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
19 changes: 16 additions & 3 deletions lib/em-synchrony/tcpsocket.rb
Expand Up @@ -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
Expand All @@ -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)
Expand Down
33 changes: 33 additions & 0 deletions spec/tcpsocket_spec.rb
Expand Up @@ -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.