Issue #13851 has been updated by chucke (Tiago Cardoso).


I've finally managed to isolate the issue, and found the issue: it was my error. Basically what was happening was that I was monitoring fds for read/write events; sometimes, the same fd returns for read/write, and in those loops, I was scheduling the fd twice, to separate workers, where they'd go through read logic around the same time. When not using the buffer, it would "just work", one read would return bytes, the other wouldn't, and both workers would continue; The same doesn't happen when passing a string as buffer (this might be locking the string internally).

I think this one is fixed. If I could complain about something, was that the error message wasn't very helpful. But I can't come up with a better one. 

So, after I found that out, I noticed something really strange: Using the `IO#read_nonblock(nread, buffer, exception: false)` reduces the throughput of my solution significantly (it also uses up significantly more memory). When using both `IO#read_nonblock(nread, exception: false)` and `IO#read_nonblock(nread, buffer)`, I get optimal performance. 

This might be a bit off-topic. Should I open a new ticket with my findings?

----------------------------------------
Bug #13851: getting "can't modify string; temporarily locked" on non-frozen instances
https://bugs.ruby-lang.org/issues/13851#change-66542

* Author: chucke (Tiago Cardoso)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: 2.3.4
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
I'm doing some nonblocking IO, and using a local string for buffering to avoid allocations. Roughly the following

```ruby
class A

  def initialize
    @buffer = String.new("", encoding: Encoding::BINARY)
  end

  def read(io)
     io.read_nonblock(16_384, @buffer, exception: false)
     # do stuff...
     @buffer.clear
  end

```

It all goes smoothly, mostly... until I start getting arbitrary error when calling `#read_nonblock`.  Here's an example backtrace:

```
DEBUG: can't modify string; temporarily locked- - - [30/Aug/2017:13:15:09 +0300] "GET / 1.0" 200 - 0.0000
DEBUG: <internal:prelude>:76:in `__read_nonblock'
DEBUG: <internal:prelude>:76:in `read_nonblock'
DEBUG: /Users/user/Projects/project:NN in `read``
....
```

I can't unfortunately reproduce this in a deterministic way. I can only say that the `read` routine is called in multiple threads (different io's instances of that class). The errors come seldom, however.


I'm running ruby 2.3.4, and the frozen string literal is activated for the file where the class is defined. I first assumed that it was the buffer, but due to its initialization, it should be marken as not-frozen. 





-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>