Skip to content

Deadlock in Concurrent::Array's on non-MRI #627

Open
@eregon

Description

@eregon
  • concurrent-ruby version: 1.0.4
  • concurrent-ruby-ext installed: no
  • concurrent-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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA bug in the library or documentation.looking-for-contributorWe are looking for a contributor to help with this issue.medium-priorityShould be done soon.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions