Description
concurrent-ruby
version: 1.0.4concurrent-ruby-ext
installed: noconcurrent-ruby-edge
used: no
Take the following code: https://gist.github.com/eregon/323890bfff539f8a33f66d8b2f02cc99
Of course, its purpose is to create a deadlock but it means any method taking a block on Array can cause a deadlock as long as:
- 2+ threads use 2+
Concurrent::Array
by calling a method taking a block - inside the blocks, the threads call any method taking on another
Concurrent::Array
This seems not such a rare scenario, as it is frequent to call methods in a block that do not only involve the current Array.
The deadlock does not happen on MRI, as it uses a single global lock and concurrent-ruby just subclasses ::Array
. It does happen on all other implementations though, like JRuby, Rubinius and TruffleRuby.
The documentation says:
A thread-safe subclass of Array.
This version locks against the object itself for every method call,
ensuring only one thread can be reading or writing at a time.
This includes iteration methods like #each.
So indeed this might imply the deadlock above, but it's not clear.
ensuring only one thread can be reading or writing at a time
is also inaccurate on MRI for methods taking a block, as they release the GIL and might switch to another Thread in the middle of e.g. #each
.
The same apply for Hash.
Is this behavior intended? Should this be fixed?
Should it behave the same on the different implementations?