Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

sendmesg (blocking) of class BasicSocket crashes the thread of the thread pool #2362

Closed
josemic opened this Issue · 2 comments

3 participants

@josemic
ruby -v
rubinius 2.0.0.rc1 (1.8.7 96db2d8e yyyy-mm-dd JI) [x86_64-unknown-linux-gnu]

uname -a
Linux donald 3.2.0-4-amd64 #1 SMP Debian 3.2.41-2+deb7u2 x86_64 GNU/Linux

The error occurs with the method "sendmesg" (blocking) of class BasicSocket on Ruby rubinius, but does not occur on RMI Ruby 1.9.3-p392 (rvm). RMI Ruby 2.0.0-p0 (rvm) works partially. See bug report http://bugs.ruby-lang.org/issues/8442.

The error does not occur with the method "send" (non-blocking) of class BasicSocket on above Rubinius version (rvm), Ruby 1.9.3-p392 (rvm) and Ruby 2.0.0-p0 (rvm).

The bug can be reproduced with the code found in the following gist.

https://gist.github.com/josemic/5653157

How to reproduce the error:

run:

ruby halfsync_halfasync.rb

on second terminal (unix):

telnet localhost 10001

on Windows use telnet client e.g. putty and make sure to configure putty as passive ("Connection->Telnet->Telnet negotiation mode: Passive")

What the code does:

  • It implements the halfsync_halfasync design-pattern (see references in the code).

  • An EchoAcceptor is registered with the reactor to accept connection setup.

  • A thread pool is started waiting for tasks to be retrieved from a shared queue
  • Upon connection-setup of the telnet the EchoAcceptor is called and registers an EchoServerHandler with the Reactor to handle data received via the connection from the telnet client.
  • Upon reception of data via the telent connection, the EchoServerHandler assembles data until a newline (\n or \r\n) is received. When that is received, the whole line is put into the shared queue.
  • The first thread from the thread pool waiting grabs the received data and the socket from the shared queue and in line 50/51 adds the thread-ID, the number of messages handled by that thread and sends it as a reply to the sender using the received socket.

  • What to expect as output:
    Upon entering e.g. text "!1234" and pressing return

  • On Ruby 1.9.3-p392 on Linux:
    See the as response the thread ID, the number of messages within the thread and the text.

  • On rubinius 2.0.0.rc1 (1.8.7 96db2d8 yyyy-mm-dd JI) [x86_64-unknown-linux-gnu]:
    No response to telnet is sent, but the sending thread crashes.

  • Everything works fine, if instead of blocking send (line 50/51) the non-blocking send (line 52/53) is used. However correct implementation of the halfsync-halfasync pattern, requires reasonably the usage of blocking "sendmesg" in thread pool.

  • I have to apologize that the program to reproduce the error is slightly large and complicated, but I believe that there is value, when ruby is able to run well known design patterns correctly.

  • A similar bug is filed for Ruby MRI here:
    http://bugs.ruby-lang.org/issues/8442

  • A similar bug is filed for JRuby here:
    http://jira.codehaus.org/browse/JRUBY-7169

@dbussink
Owner

Looks like this problem in Rubinius is basically that BasicSocket#sendmsg is missing and hasn't been implemented yet:

http://apidock.com/ruby/BasicSocket/sendmsg

@jc00ke jc00ke referenced this issue in rubysl/rubysl-socket
Open

missing recvmsg_nonblock and sendmsg_nonblock #4

@jc00ke
Owner

Moving over to rubysl/rubysl-socket#4

@jc00ke jc00ke closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.