Skip to content

Infinite Loop in MpscCompoundQueue.relaxedOffer when CAS fails #194

@mlex

Description

@mlex

Calling relaxedOffer on a MpscCompoundQueue with queueParallelism>1 can lead to an infinite loop when the call to failFastOffer on one of the underlying array queues returns -1 (indicating CAS failure).

The reason is, that status == parallelQueues (in https://github.com/JCTools/JCTools/blob/v2.1.0/jctools-core/src/main/java/org/jctools/queues/MpscCompoundQueue.java#L216) can only be true if the failFastOffer calls to all underlying queues return 1.

But inside the for(;;) loop, only parallelQueues-1 queues are tried. So as soon as the execution path reaches status = 0 (in https://github.com/JCTools/JCTools/blob/v2.1.0/jctools-core/src/main/java/org/jctools/queues/MpscCompoundQueue.java#L220), this can never happen.

I created a small example that provokes this situation: https://gist.github.com/mlex/02dc82d6368381ed138e2727925a90cf

To reproduce, start the example and wait for the output "Thread X didn't join after 10 seconds - probably caught in infinite loop". Afterwards attach a debugger or pull a stacktrace and you will see Thread X hanging inside MpscCompoundQueue.relaxedOffer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions